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