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