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