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