]> git.donarmstrong.com Git - mothur.git/blob - summarysharedcommand.cpp
added getCommandInfoCommand for gui
[mothur.git] / summarysharedcommand.cpp
1 /*
2  *  summarysharedcommand.cpp
3  *  Dotur
4  *
5  *  Created by Sarah Westcott on 1/2/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "summarysharedcommand.h"
11 #include "sharedsobscollectsummary.h"
12 #include "sharedchao1.h"
13 #include "sharedace.h"
14 #include "sharednseqs.h"
15 #include "sharedjabund.h"
16 #include "sharedsorabund.h"
17 #include "sharedjclass.h"
18 #include "sharedsorclass.h"
19 #include "sharedjest.h"
20 #include "sharedsorest.h"
21 #include "sharedthetayc.h"
22 #include "sharedthetan.h"
23 #include "sharedkstest.h"
24 #include "whittaker.h"
25 #include "sharedochiai.h"
26 #include "sharedanderbergs.h"
27 #include "sharedkulczynski.h"
28 #include "sharedkulczynskicody.h"
29 #include "sharedlennon.h"
30 #include "sharedmorisitahorn.h"
31 #include "sharedbraycurtis.h"
32 #include "sharedjackknife.h"
33 #include "whittaker.h"
34 #include "odum.h"
35 #include "canberra.h"
36 #include "structeuclidean.h"
37 #include "structchord.h"
38 #include "hellinger.h"
39 #include "manhattan.h"
40 #include "structpearson.h"
41 #include "soergel.h"
42 #include "spearman.h"
43 #include "structkulczynski.h"
44 #include "structchi2.h"
45 #include "speciesprofile.h"
46 #include "hamming.h"
47 #include "gower.h"
48 #include "memchi2.h"
49 #include "memchord.h"
50 #include "memeuclidean.h"
51 #include "mempearson.h"
52
53 //**********************************************************************************************************************
54 vector<string> SummarySharedCommand::setParameters(){   
55         try {
56                 CommandParameter pshared("shared", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(pshared);
57                 CommandParameter plabel("label", "String", "", "", "", "", "",false,false); parameters.push_back(plabel);
58                 CommandParameter pdistance("distance", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(pdistance);
59                 CommandParameter pcalc("calc", "Multiple", "sharedchao-sharedsobs-sharedace-jabund-sorabund-jclass-sorclass-jest-sorest-thetayc-thetan-kstest-whittaker-sharednseqs-ochiai-anderberg-skulczynski-kulczynskicody-lennon-morisitahorn-braycurtis-odum-canberra-structeuclidean-structchord-hellinger-manhattan-structpearson-soergel-spearman-structkulczynski-speciesprofile-structchi2-hamming-gower-memchi2-memchord-memeuclidean-mempearson", "sharedsobs-sharedchao-sharedace-jabund-sorabund-jclass-sorclass-jest-sorest-thetayc-thetan", "", "", "",true,false); parameters.push_back(pcalc);
60                 CommandParameter pall("all", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(pall);
61                 CommandParameter pprocessors("processors", "Number", "", "1", "", "", "",false,false); parameters.push_back(pprocessors);
62                 CommandParameter pgroups("groups", "String", "", "", "", "", "",false,false); parameters.push_back(pgroups);
63                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir);
64                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir);
65                 
66                 vector<string> myArray;
67                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
68                 return myArray;
69         }
70         catch(exception& e) {
71                 m->errorOut(e, "SummarySharedCommand", "setParameters");
72                 exit(1);
73         }
74 }
75 //**********************************************************************************************************************
76 string SummarySharedCommand::getHelpString(){   
77         try {
78                 string helpString = "";
79                 ValidCalculators validCalculator;
80                 helpString += "The summary.shared command parameters are shared, label, calc, distance, processors and all.  shared is required if there is no current sharedfile.\n";
81                 helpString += "The summary.shared command should be in the following format: \n";
82                 helpString += "summary.shared(label=yourLabel, calc=yourEstimators, groups=yourGroups).\n";
83                 helpString += "Example summary.shared(label=unique-.01-.03, groups=B-C, calc=sharedchao-sharedace-jabund-sorensonabund-jclass-sorclass-jest-sorest-thetayc-thetan).\n";
84                 helpString +=  validCalculator.printCalc("sharedsummary");
85                 helpString += "The default value for calc is sharedsobs-sharedchao-sharedace-jabund-sorensonabund-jclass-sorclass-jest-sorest-thetayc-thetan\n";
86                 helpString += "The default value for groups is all the groups in your groupfile.\n";
87                 helpString += "The distance parameter allows you to indicate you would like a distance file created for each calculator for each label, default=f.\n";
88                 helpString += "The label parameter is used to analyze specific labels in your input.\n";
89                 helpString += "The all parameter is used to specify if you want the estimate of all your groups together.  This estimate can only be made for sharedsobs and sharedchao calculators. The default is false.\n";
90                 helpString += "If you use sharedchao and run into memory issues, set all to false. \n";
91                 helpString += "The groups parameter allows you to specify which of the groups in your groupfile you would like analyzed.  You must enter at least 2 valid groups.\n";
92                 helpString += "Note: No spaces between parameter labels (i.e. label), '=' and parameters (i.e.yourLabel).\n";
93                 return helpString;
94         }
95         catch(exception& e) {
96                 m->errorOut(e, "SummarySharedCommand", "getHelpString");
97                 exit(1);
98         }
99 }
100 //**********************************************************************************************************************
101 SummarySharedCommand::SummarySharedCommand(){   
102         try {
103                 abort = true; calledHelp = true; 
104                 setParameters();
105                 vector<string> tempOutNames;
106                 outputTypes["summary"] = tempOutNames;
107         }
108         catch(exception& e) {
109                 m->errorOut(e, "SummarySharedCommand", "SummarySharedCommand");
110                 exit(1);
111         }
112 }
113 //**********************************************************************************************************************
114
115 SummarySharedCommand::SummarySharedCommand(string option)  {
116         try {
117                 abort = false; calledHelp = false;   
118                 allLines = 1;
119                                 
120                 //allow user to run help
121                 if(option == "help") {  help(); abort = true; calledHelp = true; }
122                 
123                 else {
124                         vector<string> myArray = setParameters();
125                         
126                         OptionParser parser(option);
127                         map<string, string> parameters = parser.getParameters();
128                         map<string, string>::iterator it;
129                         
130                         ValidParameters validParameter;
131                 
132                         //check to make sure all parameters are valid for command
133                         for (map<string, string>::iterator it = parameters.begin(); it != parameters.end(); it++) { 
134                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
135                         }
136                         
137                         //initialize outputTypes
138                         vector<string> tempOutNames;
139                         outputTypes["summary"] = tempOutNames;
140                         
141                         //if the user changes the input directory command factory will send this info to us in the output parameter 
142                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
143                         if (inputDir == "not found"){   inputDir = "";          }
144                         else {
145                                 string path;
146                                 it = parameters.find("shared");
147                                 //user has given a template file
148                                 if(it != parameters.end()){ 
149                                         path = m->hasPath(it->second);
150                                         //if the user has not given a path then, add inputdir. else leave path alone.
151                                         if (path == "") {       parameters["shared"] = inputDir + it->second;           }
152                                 }
153                         }
154                         
155                         //get shared file
156                         sharedfile = validParameter.validFile(parameters, "shared", true);
157                         if (sharedfile == "not open") { sharedfile = ""; abort = true; }        
158                         else if (sharedfile == "not found") { 
159                                 //if there is a current shared file, use it
160                                 sharedfile = m->getSharedFile(); 
161                                 if (sharedfile != "") { m->mothurOut("Using " + sharedfile + " as input file for the shared parameter."); m->mothurOutEndLine(); }
162                                 else {  m->mothurOut("You have no current sharedfile and the shared parameter is required."); m->mothurOutEndLine(); abort = true; }
163                         }
164                         
165                         
166                         //if the user changes the output directory command factory will send this info to us in the output parameter 
167                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = m->hasPath(sharedfile);             }
168                         
169
170                         //check for optional parameter and set defaults
171                         // ...at some point should added some additional type checking...
172                         label = validParameter.validFile(parameters, "label", false);                   
173                         if (label == "not found") { label = ""; }
174                         else { 
175                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
176                                 else { allLines = 1;  }
177                         }
178                         
179                                         
180                         calc = validParameter.validFile(parameters, "calc", false);                     
181                         if (calc == "not found") { calc = "sharedsobs-sharedchao-sharedace-jabund-sorabund-jclass-sorclass-jest-sorest-thetayc-thetan";  }
182                         else { 
183                                  if (calc == "default")  {  calc = "sharedsobs-sharedchao-sharedace-jabund-sorabund-jclass-sorclass-jest-sorest-thetayc-thetan";  }
184                         }
185                         m->splitAtDash(calc, Estimators);
186                         
187                         groups = validParameter.validFile(parameters, "groups", false);                 
188                         if (groups == "not found") { groups = ""; }
189                         else { 
190                                 m->splitAtDash(groups, Groups);
191                                 m->Groups = Groups;
192                         }
193                         
194                         string temp = validParameter.validFile(parameters, "all", false);                               if (temp == "not found") { temp = "false"; }
195                         all = m->isTrue(temp);
196                         
197                         temp = validParameter.validFile(parameters, "distance", false);                                 if (temp == "not found") { temp = "false"; }
198                         createPhylip = m->isTrue(temp);
199                         
200                         temp = validParameter.validFile(parameters, "processors", false);       if (temp == "not found"){       temp = m->getProcessors();      }
201                         m->setProcessors(temp);
202                         convert(temp, processors); 
203                         
204                         if (abort == false) {
205                         
206                                 ValidCalculators validCalculator;
207                                 int i;
208                                 
209                                 for (i=0; i<Estimators.size(); i++) {
210                                         if (validCalculator.isValidCalculator("sharedsummary", Estimators[i]) == true) { 
211                                                 if (Estimators[i] == "sharedsobs") { 
212                                                         sumCalculators.push_back(new SharedSobsCS());
213                                                 }else if (Estimators[i] == "sharedchao") { 
214                                                         sumCalculators.push_back(new SharedChao1());
215                                                 }else if (Estimators[i] == "sharedace") { 
216                                                         sumCalculators.push_back(new SharedAce());
217                                                 }else if (Estimators[i] == "jabund") {  
218                                                         sumCalculators.push_back(new JAbund());
219                                                 }else if (Estimators[i] == "sorabund") { 
220                                                         sumCalculators.push_back(new SorAbund());
221                                                 }else if (Estimators[i] == "jclass") { 
222                                                         sumCalculators.push_back(new Jclass());
223                                                 }else if (Estimators[i] == "sorclass") { 
224                                                         sumCalculators.push_back(new SorClass());
225                                                 }else if (Estimators[i] == "jest") { 
226                                                         sumCalculators.push_back(new Jest());
227                                                 }else if (Estimators[i] == "sorest") { 
228                                                         sumCalculators.push_back(new SorEst());
229                                                 }else if (Estimators[i] == "thetayc") { 
230                                                         sumCalculators.push_back(new ThetaYC());
231                                                 }else if (Estimators[i] == "thetan") { 
232                                                         sumCalculators.push_back(new ThetaN());
233                                                 }else if (Estimators[i] == "kstest") { 
234                                                         sumCalculators.push_back(new KSTest());
235                                                 }else if (Estimators[i] == "sharednseqs") { 
236                                                         sumCalculators.push_back(new SharedNSeqs());
237                                                 }else if (Estimators[i] == "ochiai") { 
238                                                         sumCalculators.push_back(new Ochiai());
239                                                 }else if (Estimators[i] == "anderberg") { 
240                                                         sumCalculators.push_back(new Anderberg());
241                                                 }else if (Estimators[i] == "kulczynski") { 
242                                                         sumCalculators.push_back(new Kulczynski());
243                                                 }else if (Estimators[i] == "kulczynskicody") { 
244                                                         sumCalculators.push_back(new KulczynskiCody());
245                                                 }else if (Estimators[i] == "lennon") { 
246                                                         sumCalculators.push_back(new Lennon());
247                                                 }else if (Estimators[i] == "morisitahorn") { 
248                                                         sumCalculators.push_back(new MorHorn());
249                                                 }else if (Estimators[i] == "braycurtis") { 
250                                                         sumCalculators.push_back(new BrayCurtis());
251                                                 }else if (Estimators[i] == "whittaker") { 
252                                                         sumCalculators.push_back(new Whittaker());
253                                                 }else if (Estimators[i] == "odum") { 
254                                                         sumCalculators.push_back(new Odum());
255                                                 }else if (Estimators[i] == "canberra") { 
256                                                         sumCalculators.push_back(new Canberra());
257                                                 }else if (Estimators[i] == "structeuclidean") { 
258                                                         sumCalculators.push_back(new StructEuclidean());
259                                                 }else if (Estimators[i] == "structchord") { 
260                                                         sumCalculators.push_back(new StructChord());
261                                                 }else if (Estimators[i] == "hellinger") { 
262                                                         sumCalculators.push_back(new Hellinger());
263                                                 }else if (Estimators[i] == "manhattan") { 
264                                                         sumCalculators.push_back(new Manhattan());
265                                                 }else if (Estimators[i] == "structpearson") { 
266                                                         sumCalculators.push_back(new StructPearson());
267                                                 }else if (Estimators[i] == "soergel") { 
268                                                         sumCalculators.push_back(new Soergel());
269                                                 }else if (Estimators[i] == "spearman") { 
270                                                         sumCalculators.push_back(new Spearman());
271                                                 }else if (Estimators[i] == "structkulczynski") { 
272                                                         sumCalculators.push_back(new StructKulczynski());
273                                                 }else if (Estimators[i] == "speciesprofile") { 
274                                                         sumCalculators.push_back(new SpeciesProfile());
275                                                 }else if (Estimators[i] == "hamming") { 
276                                                         sumCalculators.push_back(new Hamming());
277                                                 }else if (Estimators[i] == "structchi2") { 
278                                                         sumCalculators.push_back(new StructChi2());
279                                                 }else if (Estimators[i] == "gower") { 
280                                                         sumCalculators.push_back(new Gower());
281                                                 }else if (Estimators[i] == "memchi2") { 
282                                                         sumCalculators.push_back(new MemChi2());
283                                                 }else if (Estimators[i] == "memchord") { 
284                                                         sumCalculators.push_back(new MemChord());
285                                                 }else if (Estimators[i] == "memeuclidean") { 
286                                                         sumCalculators.push_back(new MemEuclidean());
287                                                 }else if (Estimators[i] == "mempearson") { 
288                                                         sumCalculators.push_back(new MemPearson());
289                                                 }
290                                         }
291                                 }
292                                 
293                                 mult = false;
294                         }
295                 }
296         }
297         catch(exception& e) {
298                 m->errorOut(e, "SummarySharedCommand", "SummarySharedCommand");
299                 exit(1);
300         }
301 }
302 //**********************************************************************************************************************
303
304 int SummarySharedCommand::execute(){
305         try {
306         
307                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
308                 
309                 ofstream outputFileHandle, outAll;
310                 string outputFileName = outputDir + m->getRootName(m->getSimpleName(sharedfile)) + "shared.summary";
311                 
312                 //if the users entered no valid calculators don't execute command
313                 if (sumCalculators.size() == 0) { return 0; }
314                 //check if any calcs can do multiples
315                 else{
316                         if (all){ 
317                                 for (int i = 0; i < sumCalculators.size(); i++) {
318                                         if (sumCalculators[i]->getMultiple() == true) { mult = true; }
319                                 }
320                         }
321                 }
322                         
323                 input = new InputData(sharedfile, "sharedfile");
324                 lookup = input->getSharedRAbundVectors();
325                 string lastLabel = lookup[0]->getLabel();
326         
327                 /******************************************************/
328                 //output headings for files
329                 /******************************************************/
330                 //output estimator names as column headers
331                 m->openOutputFile(outputFileName, outputFileHandle);
332                 outputFileHandle << "label" <<'\t' << "comparison" << '\t'; 
333                 for(int i=0;i<sumCalculators.size();i++){
334                         outputFileHandle << '\t' << sumCalculators[i]->getName();
335                         if (sumCalculators[i]->getCols() == 3) {   outputFileHandle << "\t" << sumCalculators[i]->getName() << "_lci\t" << sumCalculators[i]->getName() << "_hci";  }
336                 }
337                 outputFileHandle << endl;
338                 outputFileHandle.close();
339                 
340                 //create file and put column headers for multiple groups file
341                 string outAllFileName = ((m->getRootName(sharedfile)) + "sharedmultiple.summary");
342                 if (mult == true) {
343                         m->openOutputFile(outAllFileName, outAll);
344                         outputNames.push_back(outAllFileName);
345                         
346                         outAll << "label" <<'\t' << "comparison" << '\t'; 
347                         for(int i=0;i<sumCalculators.size();i++){
348                                 if (sumCalculators[i]->getMultiple() == true) { 
349                                         outAll << '\t' << sumCalculators[i]->getName();
350                                 }
351                         }
352                         outAll << endl;
353                         outAll.close();
354                 }
355                 
356                 if (lookup.size() < 2) { 
357                         m->mothurOut("I cannot run the command without at least 2 valid groups."); 
358                         for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
359                         
360                         //close files and clean up
361                         remove(outputFileName.c_str());
362                         if (mult == true) { remove(outAllFileName.c_str());  }
363                         return 0;
364                 //if you only have 2 groups you don't need a .sharedmultiple file
365                 }else if ((lookup.size() == 2) && (mult == true)) { 
366                         mult = false;
367                         remove(outAllFileName.c_str());
368                         outputNames.pop_back();
369                 }
370                 
371                 if (m->control_pressed) {
372                         if (mult) {  remove(outAllFileName.c_str());  }
373                         remove(outputFileName.c_str()); 
374                         delete input;
375                         for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
376                         for(int i=0;i<sumCalculators.size();i++){  delete sumCalculators[i]; }
377                         m->Groups.clear(); 
378                         return 0;
379                 }
380                 /******************************************************/
381                 
382                 
383                 /******************************************************/
384                 //comparison breakup to be used by different processes later
385                 numGroups = m->Groups.size();
386                 lines.resize(processors);
387                 for (int i = 0; i < processors; i++) {
388                         lines[i].start = int (sqrt(float(i)/float(processors)) * numGroups);
389                         lines[i].end = int (sqrt(float(i+1)/float(processors)) * numGroups);
390                 }               
391                 /******************************************************/
392                 
393                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
394                 set<string> processedLabels;
395                 set<string> userLabels = labels;
396                         
397                 //as long as you are not at the end of the file or done wih the lines you want
398                 while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
399                         if (m->control_pressed) {
400                                 if (mult) {  remove(outAllFileName.c_str());  }
401                                 remove(outputFileName.c_str()); 
402                                 delete input; 
403                                 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; }
404                                 for(int i=0;i<sumCalculators.size();i++){  delete sumCalculators[i]; }
405                                 m->Groups.clear(); 
406                                 return 0;
407                         }
408
409                 
410                         if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
411                                 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
412                                 process(lookup, outputFileName, outAllFileName);
413                                 
414                                 processedLabels.insert(lookup[0]->getLabel());
415                                 userLabels.erase(lookup[0]->getLabel());
416                         }
417                         
418                         if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
419                                         string saveLabel = lookup[0]->getLabel();
420                                         
421                                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
422                                         lookup = input->getSharedRAbundVectors(lastLabel);
423
424                                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
425                                         process(lookup, outputFileName, outAllFileName);
426                                         
427                                         processedLabels.insert(lookup[0]->getLabel());
428                                         userLabels.erase(lookup[0]->getLabel());
429                                         
430                                         //restore real lastlabel to save below
431                                         lookup[0]->setLabel(saveLabel);
432                         }
433                         
434                         lastLabel = lookup[0]->getLabel();                      
435                                 
436                         //get next line to process
437                         //prevent memory leak
438                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
439                         lookup = input->getSharedRAbundVectors();
440                 }
441                 
442                 if (m->control_pressed) {
443                         if (mult) { remove(outAllFileName.c_str());  }
444                         remove(outputFileName.c_str()); 
445                         delete input; 
446                         for(int i=0;i<sumCalculators.size();i++){  delete sumCalculators[i]; }
447                         m->Groups.clear(); 
448                         return 0;
449                 }
450
451                 //output error messages about any remaining user labels
452                 set<string>::iterator it;
453                 bool needToRun = false;
454                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
455                         m->mothurOut("Your file does not include the label " + *it); 
456                         if (processedLabels.count(lastLabel) != 1) {
457                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
458                                 needToRun = true;
459                         }else {
460                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
461                         }
462                 }
463                 
464                 //run last label if you need to
465                 if (needToRun == true)  {
466                                 for (int i = 0; i < lookup.size(); i++) {  if (lookup[i] != NULL) {     delete lookup[i];       } } 
467                                 lookup = input->getSharedRAbundVectors(lastLabel);
468
469                                 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
470                                 process(lookup, outputFileName, outAllFileName);
471                                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
472                 }
473                 
474                                 
475                 //reset groups parameter
476                 m->Groups.clear();  
477                 
478                 for(int i=0;i<sumCalculators.size();i++){  delete sumCalculators[i]; }
479                 delete input;  
480                 
481                 if (m->control_pressed) {
482                         remove(outAllFileName.c_str());  
483                         remove(outputFileName.c_str()); 
484                         return 0;
485                 }
486                 
487                 m->mothurOutEndLine();
488                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
489                 m->mothurOut(outputFileName); m->mothurOutEndLine();    
490                 if (mult) { m->mothurOut(outAllFileName); m->mothurOutEndLine();        outputTypes["summary"].push_back(outAllFileName); }
491                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    } outputTypes["summary"].push_back(outputFileName);
492                 m->mothurOutEndLine();
493
494                 return 0;
495         }
496         catch(exception& e) {
497                 m->errorOut(e, "SummarySharedCommand", "execute");
498                 exit(1);
499         }
500 }
501
502 /***********************************************************/
503 int SummarySharedCommand::process(vector<SharedRAbundVector*> thisLookup, string sumFileName, string sumAllFileName) {
504         try {
505                         vector< vector<seqDist> > calcDists;  //vector containing vectors that contains the summary results for each group compare
506                         calcDists.resize(sumCalculators.size()); //one for each calc, this will be used to make .dist files
507                                 
508                         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
509                                 if(processors == 1){
510                                         driver(thisLookup, 0, numGroups, sumFileName+".temp", sumAllFileName+".temp", calcDists);
511                                         m->appendFiles((sumFileName + ".temp"), sumFileName);
512                                         remove((sumFileName + ".temp").c_str());
513                                         if (mult) {
514                                                 m->appendFiles((sumAllFileName + ".temp"), sumAllFileName);
515                                                 remove((sumAllFileName + ".temp").c_str());
516                                         }
517                                 }else{
518                                         int process = 1;
519                                         vector<int> processIDS;
520                 
521                                         //loop through and create all the processes you want
522                                         while (process != processors) {
523                                                 int pid = fork();
524                                                 
525                                                 if (pid > 0) {
526                                                         processIDS.push_back(pid); 
527                                                         process++;
528                                                 }else if (pid == 0){
529                                                         driver(thisLookup, lines[process].start, lines[process].end, sumFileName + toString(getpid()) + ".temp", sumAllFileName + toString(getpid()) + ".temp", calcDists);   
530                                                         
531                                                         //only do this if you want a distance file
532                                                         if (createPhylip) {
533                                                                 string tempdistFileName = m->getRootName(m->getSimpleName(sumFileName)) + toString(getpid()) + ".dist";
534                                                                 ofstream outtemp;
535                                                                 m->openOutputFile(tempdistFileName, outtemp);
536                                                                 
537                                                                 for (int i = 0; i < calcDists.size(); i++) {
538                                                                         outtemp << calcDists[i].size() << endl;
539                                                                         
540                                                                         for (int j = 0; j < calcDists[i].size(); j++) {
541                                                                                 outtemp << calcDists[i][j].seq1 << '\t' << calcDists[i][j].seq2 << '\t' << calcDists[i][j].dist << endl;
542                                                                         }
543                                                                 }
544                                                                 outtemp.close();
545                                                         }
546                                                         
547                                                         exit(0);
548                                                 }else { 
549                                                         m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
550                                                         for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
551                                                         exit(0);
552                                                 }
553                                         }
554                                         
555                                         //parent do your part
556                                         driver(thisLookup, lines[0].start, lines[0].end, sumFileName + toString(getpid()) + ".temp", sumAllFileName + toString(getpid()) + ".temp", calcDists);   
557                                         m->appendFiles((sumFileName + toString(getpid()) + ".temp"), sumFileName);
558                                         remove((sumFileName + toString(getpid()) + ".temp").c_str());
559                                         if (mult) { m->appendFiles((sumAllFileName + toString(getpid()) + ".temp"), sumAllFileName); }
560                                                 
561                                         //force parent to wait until all the processes are done
562                                         for (int i = 0; i < processIDS.size(); i++) {
563                                                 int temp = processIDS[i];
564                                                 wait(&temp);
565                                         }
566                                         
567                                         for (int i = 0; i < processIDS.size(); i++) {
568                                                 m->appendFiles((sumFileName + toString(processIDS[i]) + ".temp"), sumFileName);
569                                                 remove((sumFileName + toString(processIDS[i]) + ".temp").c_str());
570                                                 if (mult) {     remove((sumAllFileName + toString(processIDS[i]) + ".temp").c_str());   }
571                                                 
572                                                 if (createPhylip) {
573                                                         string tempdistFileName = m->getRootName(m->getSimpleName(sumFileName)) + toString(processIDS[i]) +  ".dist";
574                                                         ifstream intemp;
575                                                         m->openInputFile(tempdistFileName, intemp);
576                                                         
577                                                         for (int i = 0; i < calcDists.size(); i++) {
578                                                                 int size = 0;
579                                                                 intemp >> size; m->gobble(intemp);
580                                                                         
581                                                                 for (int j = 0; j < size; j++) {
582                                                                         int seq1 = 0;
583                                                                         int seq2 = 0;
584                                                                         float dist = 1.0;
585                                                                         
586                                                                         intemp >> seq1 >> seq2 >> dist;   m->gobble(intemp);
587                                                                         
588                                                                         seqDist tempDist(seq1, seq2, dist);
589                                                                         calcDists[i].push_back(tempDist);
590                                                                 }
591                                                         }
592                                                         intemp.close();
593                                                         remove(tempdistFileName.c_str());
594                                                 }
595                                         }
596
597                                 }
598                         #else
599                                 driver(thisLookup, 0, numGroups, (sumFileName + ".temp"), (sumAllFileName + ".temp"), calcDists);
600                                 m->appendFiles((sumFileName + ".temp"), sumFileName);
601                                 remove((sumFileName + ".temp").c_str());
602                                 if (mult) {
603                                         m->appendFiles((sumAllFileName + ".temp"), sumAllFileName);
604                                         remove((sumAllFileName + ".temp").c_str());
605                                 }
606                         #endif
607                         
608                         if (createPhylip) {
609                                 for (int i = 0; i < calcDists.size(); i++) {
610                                         if (m->control_pressed) { break; }
611                                 
612                                         string distFileName = outputDir + m->getRootName(m->getSimpleName(sumFileName)) + sumCalculators[i]->getName() + "." + thisLookup[0]->getLabel() + ".dist";
613                                         outputNames.push_back(distFileName);
614                                         ofstream outDist;
615                                         m->openOutputFile(distFileName, outDist);
616                                         outDist.setf(ios::fixed, ios::floatfield); outDist.setf(ios::showpoint);
617                                         
618                                         //initialize matrix
619                                         vector< vector<float> > matrix; //square matrix to represent the distance
620                                         matrix.resize(thisLookup.size());
621                                         for (int k = 0; k < thisLookup.size(); k++) {  matrix[k].resize(thisLookup.size(), 0.0); }
622                                         
623                                         
624                                         for (int j = 0; j < calcDists[i].size(); j++) {
625                                                 int row = calcDists[i][j].seq1;
626                                                 int column = calcDists[i][j].seq2;
627                                                 float dist = calcDists[i][j].dist;
628                                                 
629                                                 matrix[row][column] = dist;
630                                                 matrix[column][row] = dist;
631                                         }
632                                         
633                                         //output to file
634                                         outDist << thisLookup.size() << endl;
635                                         for (int r=0; r<thisLookup.size(); r++) { 
636                                                 //output name
637                                                 string name = thisLookup[r]->getGroup();
638                                                 if (name.length() < 10) { //pad with spaces to make compatible
639                                                         while (name.length() < 10) {  name += " ";  }
640                                                 }
641                                                 outDist << name << '\t';
642                                         
643                                                 //output distances
644                                                 for (int l = 0; l < r; l++) {   outDist  << matrix[r][l] << '\t';  }
645                                                 outDist << endl;
646                                         }
647                                         
648                                         outDist.close();
649                                 }
650                         }
651                 return 0;
652         }
653         catch(exception& e) {
654                 m->errorOut(e, "SummarySharedCommand", "process");
655                 exit(1);
656         }
657 }
658 /**************************************************************************************************/
659 int SummarySharedCommand::driver(vector<SharedRAbundVector*> thisLookup, int start, int end, string sumFile, string sumAllFile, vector< vector<seqDist> >& calcDists) { 
660         try {
661                 
662                 //loop through calculators and add to file all for all calcs that can do mutiple groups
663                 if (mult == true) {
664                         ofstream outAll;
665                         m->openOutputFile(sumAllFile, outAll);
666                         
667                         //output label
668                         outAll << thisLookup[0]->getLabel() << '\t';
669                         
670                         //output groups names
671                         string outNames = "";
672                         for (int j = 0; j < thisLookup.size(); j++) {
673                                 outNames += thisLookup[j]->getGroup() +  "-";
674                         }
675                         outNames = outNames.substr(0, outNames.length()-1); //rip off extra '-';
676                         outAll << outNames << '\t';
677                         
678                         for(int i=0;i<sumCalculators.size();i++){
679                                 if (sumCalculators[i]->getMultiple() == true) { 
680                                         sumCalculators[i]->getValues(thisLookup);
681                                         
682                                         if (m->control_pressed) { outAll.close(); return 1; }
683                                         
684                                         outAll << '\t';
685                                         sumCalculators[i]->print(outAll);
686                                 }
687                         }
688                         outAll << endl;
689                         outAll.close();
690                 }
691                 
692                 ofstream outputFileHandle;
693                 m->openOutputFile(sumFile, outputFileHandle);
694                 
695                 vector<SharedRAbundVector*> subset;
696                 for (int k = start; k < end; k++) { // pass cdd each set of groups to compare
697
698                         for (int l = 0; l < k; l++) {
699                                 
700                                 outputFileHandle << thisLookup[0]->getLabel() << '\t';
701                                 
702                                 subset.clear(); //clear out old pair of sharedrabunds
703                                 //add new pair of sharedrabunds
704                                 subset.push_back(thisLookup[k]); subset.push_back(thisLookup[l]); 
705                                 
706                                 //sort groups to be alphanumeric
707                                 if (thisLookup[k]->getGroup() > thisLookup[l]->getGroup()) {
708                                         outputFileHandle << (thisLookup[l]->getGroup() +'\t' + thisLookup[k]->getGroup()) << '\t'; //print out groups
709                                 }else{
710                                         outputFileHandle << (thisLookup[k]->getGroup() +'\t' + thisLookup[l]->getGroup()) << '\t'; //print out groups
711                                 }
712                                 
713                                 for(int i=0;i<sumCalculators.size();i++) {
714                                         
715                                         //if this calc needs all groups to calculate the pair load all groups
716                                         if (sumCalculators[i]->getNeedsAll()) { 
717                                                 //load subset with rest of lookup for those calcs that need everyone to calc for a pair
718                                                 for (int w = 0; w < thisLookup.size(); w++) {
719                                                         if ((w != k) && (w != l)) { subset.push_back(thisLookup[w]); }
720                                                 }
721                                         }
722                                         
723                                         vector<double> tempdata = sumCalculators[i]->getValues(subset); //saves the calculator outputs
724                                         
725                                         if (m->control_pressed) { outputFileHandle.close(); return 1; }
726                                         
727                                         outputFileHandle << '\t';
728                                         sumCalculators[i]->print(outputFileHandle);
729                                         
730                                         seqDist temp(l, k, (1.0 - tempdata[0]));
731                                         calcDists[i].push_back(temp);
732                                 }
733                                 outputFileHandle << endl;
734                         }
735                 }
736                 
737                 outputFileHandle.close();
738                 
739                 return 0;
740         }
741         catch(exception& e) {
742                 m->errorOut(e, "SummarySharedCommand", "driver");
743                 exit(1);
744         }
745 }
746 /**************************************************************************************************/
747
748