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