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