]> git.donarmstrong.com Git - mothur.git/blob - treegroupscommand.cpp
working on testing
[mothur.git] / treegroupscommand.cpp
1 /*
2  *  treegroupscommand.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 4/8/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "treegroupscommand.h"
11 #include "sharedjabund.h"
12 #include "sharedsorabund.h"
13 #include "sharedjclass.h"
14 #include "sharedsorclass.h"
15 #include "sharedjest.h"
16 #include "sharedsorest.h"
17 #include "sharedthetayc.h"
18 #include "sharedthetan.h"
19 #include "sharedmorisitahorn.h"
20 #include "sharedbraycurtis.h"
21
22
23 //**********************************************************************************************************************
24
25 TreeGroupCommand::TreeGroupCommand(string option)  {
26         try {
27                 globaldata = GlobalData::getInstance();
28                 abort = false;
29                 allLines = 1;
30                 labels.clear();
31                 Groups.clear();
32                 Estimators.clear();
33                 
34                 //allow user to run help
35                 if(option == "help") { validCalculator = new ValidCalculators(); help(); abort = true; }
36                 
37                 else {
38                         //valid paramters for this command
39                         string Array[] =  {"label","calc","groups", "phylip", "column", "name", "precision","cutoff","outputdir","inputdir"};
40                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
41                         
42                         OptionParser parser(option);
43                         map<string, string> parameters = parser. getParameters();
44                         
45                         ValidParameters validParameter;
46                         map<string, string>::iterator it;
47                 
48                         //check to make sure all parameters are valid for command
49                         for (it = parameters.begin(); it != parameters.end(); it++) { 
50                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
51                         }
52                         
53                         globaldata->newRead();
54                         
55                         //if the user changes the input directory command factory will send this info to us in the output parameter 
56                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
57                         if (inputDir == "not found"){   inputDir = "";          }
58                         else {
59                                 string path;
60                                 it = parameters.find("phylip");
61                                 //user has given a template file
62                                 if(it != parameters.end()){ 
63                                         path = m->hasPath(it->second);
64                                         //if the user has not given a path then, add inputdir. else leave path alone.
65                                         if (path == "") {       parameters["phylip"] = inputDir + it->second;           }
66                                 }
67                                 
68                                 it = parameters.find("column");
69                                 //user has given a template file
70                                 if(it != parameters.end()){ 
71                                         path = m->hasPath(it->second);
72                                         //if the user has not given a path then, add inputdir. else leave path alone.
73                                         if (path == "") {       parameters["column"] = inputDir + it->second;           }
74                                 }
75                                 
76                                 it = parameters.find("name");
77                                 //user has given a template file
78                                 if(it != parameters.end()){ 
79                                         path = m->hasPath(it->second);
80                                         //if the user has not given a path then, add inputdir. else leave path alone.
81                                         if (path == "") {       parameters["name"] = inputDir + it->second;             }
82                                 }
83                         }
84                         
85                         format = globaldata->getFormat();
86                         
87                         //required parameters
88                         phylipfile = validParameter.validFile(parameters, "phylip", true);
89                         if (phylipfile == "not open") { abort = true; }
90                         else if (phylipfile == "not found") { phylipfile = ""; }        
91                         else {  format = "phylip";  globaldata->setPhylipFile(phylipfile);      }
92                         
93                         columnfile = validParameter.validFile(parameters, "column", true);
94                         if (columnfile == "not open") { abort = true; } 
95                         else if (columnfile == "not found") { columnfile = ""; }
96                         else {  format = "column"; globaldata->setColumnFile(columnfile);       }
97                         
98                         namefile = validParameter.validFile(parameters, "name", true);
99                         if (namefile == "not open") { abort = true; }   
100                         else if (namefile == "not found") { namefile = ""; }
101                         else {  globaldata->setNameFile(namefile);      }
102                         
103                         //error checking on files                       
104                         if ((globaldata->getSharedFile() == "") && ((phylipfile == "") && (columnfile == "")))  { m->mothurOut("You must run the read.otu command or provide a distance file before running the tree.shared command."); m->mothurOutEndLine(); abort = true; }
105                         else if ((phylipfile != "") && (columnfile != "")) { m->mothurOut("When running the tree.shared command with a distance file you may not use both the column and the phylip parameters."); m->mothurOutEndLine(); abort = true; }
106                         
107                         if (columnfile != "") {
108                                 if (namefile == "") {  m->mothurOut("You need to provide a namefile if you are going to use the column format."); m->mothurOutEndLine(); abort = true; }
109                         }
110
111                         //check for optional parameter and set defaults
112                         // ...at some point should added some additional type checking...
113                         label = validParameter.validFile(parameters, "label", false);                   
114                         if (label == "not found") { label = ""; }
115                         else { 
116                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
117                                 else { allLines = 1;  }
118                         }
119                         
120                         //if the user has not specified any labels use the ones from read.otu
121                         if(label == "") {  
122                                 allLines = globaldata->allLines; 
123                                 labels = globaldata->labels; 
124                         }
125                                 
126                         groups = validParameter.validFile(parameters, "groups", false);                 
127                         if (groups == "not found") { groups = ""; }
128                         else { 
129                                 m->splitAtDash(groups, Groups);
130                                 globaldata->Groups = Groups;
131                         }
132                                 
133                         calc = validParameter.validFile(parameters, "calc", false);                     
134                         if (calc == "not found") { calc = "jclass-thetayc";  }
135                         else { 
136                                  if (calc == "default")  {  calc = "jclass-thetayc";  }
137                         }
138                         m->splitAtDash(calc, Estimators);
139
140                         string temp;
141                         temp = validParameter.validFile(parameters, "precision", false);                        if (temp == "not found") { temp = "100"; }
142                         convert(temp, precision); 
143                         
144                         temp = validParameter.validFile(parameters, "cutoff", false);                   if (temp == "not found") { temp = "10"; }
145                         convert(temp, cutoff); 
146                         cutoff += (5 / (precision * 10.0));
147                         
148                         //if the user changes the output directory command factory will send this info to us in the output parameter 
149                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  
150                                 outputDir = ""; 
151                                 outputDir += m->hasPath(globaldata->inputFileName); //if user entered a file with a path then preserve it       
152                         }
153
154                                 
155                         if (abort == false) {
156                         
157                                 validCalculator = new ValidCalculators();
158                                 
159                                 if (format == "sharedfile") {
160                                         int i;
161                                         for (i=0; i<Estimators.size(); i++) {
162                                                 if (validCalculator->isValidCalculator("treegroup", Estimators[i]) == true) { 
163                                                         if (Estimators[i] == "jabund") {        
164                                                                 treeCalculators.push_back(new JAbund());
165                                                         }else if (Estimators[i] == "sorabund") { 
166                                                                 treeCalculators.push_back(new SorAbund());
167                                                         }else if (Estimators[i] == "jclass") { 
168                                                                 treeCalculators.push_back(new Jclass());
169                                                         }else if (Estimators[i] == "sorclass") { 
170                                                                 treeCalculators.push_back(new SorClass());
171                                                         }else if (Estimators[i] == "jest") { 
172                                                                 treeCalculators.push_back(new Jest());
173                                                         }else if (Estimators[i] == "sorest") { 
174                                                                 treeCalculators.push_back(new SorEst());
175                                                         }else if (Estimators[i] == "thetayc") { 
176                                                                 treeCalculators.push_back(new ThetaYC());
177                                                         }else if (Estimators[i] == "thetan") { 
178                                                                 treeCalculators.push_back(new ThetaN());
179                                                         }else if (Estimators[i] == "morisitahorn") { 
180                                                                 treeCalculators.push_back(new MorHorn());
181                                                         }else if (Estimators[i] == "braycurtis") { 
182                                                                 treeCalculators.push_back(new BrayCurtis());
183                                                         }
184                                                 }
185                                         }
186                                 }
187                         }       
188                 }
189
190         }
191         catch(exception& e) {
192                 m->errorOut(e, "TreeGroupCommand", "TreeGroupCommand");
193                 exit(1);
194         }
195 }
196
197 //**********************************************************************************************************************
198
199 void TreeGroupCommand::help(){
200         try {
201                 m->mothurOut("The tree.shared command creates a .tre to represent the similiarity between groups or sequences.\n");
202                 m->mothurOut("The tree.shared command can only be executed after a successful read.otu command or by providing a distance file.\n");
203                 m->mothurOut("The tree.shared command parameters are groups, calc, phylip, column, name, cutoff, precision and label.\n");
204                 m->mothurOut("The groups parameter allows you to specify which of the groups in your groupfile you would like included used.\n");
205                 m->mothurOut("The group names are separated by dashes. The label allow you to select what distance levels you would like trees created for, and are also separated by dashes.\n");
206                 m->mothurOut("The phylip or column parameter are required if you do not run the read.otu command first, and only one may be used.  If you use a column file the name filename is required. \n");
207                 m->mothurOut("If you do not provide a cutoff value 10.00 is assumed. If you do not provide a precision value then 100 is assumed.\n");
208                 m->mothurOut("The tree.shared command should be in the following format: tree.shared(groups=yourGroups, calc=yourCalcs, label=yourLabels).\n");
209                 m->mothurOut("Example tree.shared(groups=A-B-C, calc=jabund-sorabund).\n");
210                 m->mothurOut("The default value for groups is all the groups in your groupfile.\n");
211                 m->mothurOut("The default value for calc is jclass-thetayc.\n");
212                 m->mothurOut("The tree.shared command outputs a .tre file for each calculator you specify at each distance you choose.\n");
213                 validCalculator->printCalc("treegroup", cout);
214                 m->mothurOut("Or the tree.shared command can be in the following format: tree.shared(phylip=yourPhylipFile).\n");
215                 m->mothurOut("Example tree.shared(phylip=abrecovery.dist).\n");
216                 m->mothurOut("Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n\n");
217         }
218         catch(exception& e) {
219                 m->errorOut(e, "TreeGroupCommand", "help");
220                 exit(1);
221         }
222 }
223
224
225 //**********************************************************************************************************************
226
227 TreeGroupCommand::~TreeGroupCommand(){
228         globaldata->Groups.clear();  
229         if (abort == false) {
230                 
231                 if (format == "sharedfile") { delete read;  delete input; globaldata->ginput = NULL; }
232                 else { delete readMatrix;  delete matrix; delete list; }
233                 delete tmap;  globaldata->gTreemap = NULL;
234                 delete validCalculator;
235         }
236         
237 }
238
239 //**********************************************************************************************************************
240
241 int TreeGroupCommand::execute(){
242         try {
243         
244                 if (abort == true) { return 0; }
245                 
246                 if (format == "sharedfile") {
247                         //if the users entered no valid calculators don't execute command
248                         if (treeCalculators.size() == 0) { m->mothurOut("You have given no valid calculators."); m->mothurOutEndLine(); return 0; }
249                         
250                         if (globaldata->gGroupmap != NULL) {  delete globaldata->gGroupmap;   globaldata->gGroupmap = NULL;  }
251                         //you have groups
252                         read = new ReadOTUFile(globaldata->inputFileName);      
253                         read->read(&*globaldata); 
254                         
255                         input = globaldata->ginput;
256                         lookup = input->getSharedRAbundVectors();
257                         lastLabel = lookup[0]->getLabel();
258                         
259                         if (lookup.size() < 2) { m->mothurOut("You have not provided enough valid groups.  I cannot run the command."); m->mothurOutEndLine(); return 0; }
260                         
261                         //used in tree constructor 
262                         globaldata->runParse = false;
263                         
264                         //create treemap class from groupmap for tree class to use
265                         tmap = new TreeMap();
266                         tmap->makeSim(globaldata->gGroupmap);
267                         globaldata->gTreemap = tmap;
268                         
269                         //clear globaldatas old tree names if any
270                         globaldata->Treenames.clear();
271                         
272                         //fills globaldatas tree names
273                         globaldata->Treenames = globaldata->Groups;
274                 
275                         if (m->control_pressed) { return 0; }
276                         
277                         //create tree file
278                         makeSimsShared();
279                         
280                         if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str());  } return 0; }
281                 }else{
282                         //read in dist file
283                         filename = globaldata->inputFileName;
284                 
285                         if (format == "column") { readMatrix = new ReadColumnMatrix(filename); }        
286                         else if (format == "phylip") { readMatrix = new ReadPhylipMatrix(filename); }
287                                 
288                         readMatrix->setCutoff(cutoff);
289         
290                         if(namefile != ""){     
291                                 nameMap = new NameAssignment(namefile);
292                                 nameMap->readMap();
293                         }
294                         else{
295                                 nameMap = NULL;
296                         }
297         
298                         readMatrix->read(nameMap);
299                         list = readMatrix->getListVector();
300                         matrix = readMatrix->getMatrix();
301
302                         //make treemap
303                         tmap = new TreeMap();
304                         
305                         if (m->control_pressed) { return 0; }
306                         
307                         tmap->makeSim(list);
308                         globaldata->gTreemap = tmap;
309                         
310                         globaldata->Groups = tmap->namesOfGroups;
311                 
312                         //clear globaldatas old tree names if any
313                         globaldata->Treenames.clear();
314                 
315                         //fills globaldatas tree names
316                         globaldata->Treenames = globaldata->Groups;
317                         
318                         //used in tree constructor 
319                         globaldata->runParse = false;
320                         
321                         if (m->control_pressed) { return 0; }
322                         
323                         makeSimsDist();
324                         
325                         if (m->control_pressed) { return 0; }
326
327                         //create a new filename
328                         outputFile = outputDir + m->getRootName(m->getSimpleName(globaldata->inputFileName)) + "tre";   
329                         outputNames.push_back(outputFile);
330                                 
331                         createTree();
332                         
333                         if (m->control_pressed) { return 0; }
334
335                         m->mothurOut("Tree complete. "); m->mothurOutEndLine();
336                         
337                 }
338                                 
339                 //reset groups parameter
340                 globaldata->Groups.clear();  
341                 
342                 m->mothurOutEndLine();
343                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
344                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
345                 m->mothurOutEndLine();
346
347                 return 0;
348         }
349         catch(exception& e) {
350                 m->errorOut(e, "TreeGroupCommand", "execute");
351                 exit(1);
352         }
353 }
354 //**********************************************************************************************************************
355
356 int TreeGroupCommand::createTree(){
357         try {
358                 //create tree
359                 t = new Tree();
360                 
361                 //do merges and create tree structure by setting parents and children
362                 //there are numGroups - 1 merges to do
363                 for (int i = 0; i < (numGroups - 1); i++) {
364                         float largest = -1000.0;
365                         
366                         if (m->control_pressed) { delete t; return 1; }
367                         
368                         int row, column;
369                         //find largest value in sims matrix by searching lower triangle
370                         for (int j = 1; j < simMatrix.size(); j++) {
371                                 for (int k = 0; k < j; k++) {
372                                         if (simMatrix[j][k] > largest) {  largest = simMatrix[j][k]; row = j; column = k;  }
373                                 }
374                         }
375
376                         //set non-leaf node info and update leaves to know their parents
377                         //non-leaf
378                         t->tree[numGroups + i].setChildren(index[row], index[column]);
379                         
380                         //parents
381                         t->tree[index[row]].setParent(numGroups + i);
382                         t->tree[index[column]].setParent(numGroups + i);
383                         
384                         //blength = distance / 2;
385                         float blength = ((1.0 - largest) / 2);
386                         
387                         //branchlengths
388                         t->tree[index[row]].setBranchLength(blength - t->tree[index[row]].getLengthToLeaves());
389                         t->tree[index[column]].setBranchLength(blength - t->tree[index[column]].getLengthToLeaves());
390                         
391                         //set your length to leaves to your childs length plus branchlength
392                         t->tree[numGroups + i].setLengthToLeaves(t->tree[index[row]].getLengthToLeaves() + t->tree[index[row]].getBranchLength());
393                         
394                         
395                         //update index 
396                         index[row] = numGroups+i;
397                         index[column] = numGroups+i;
398                         
399                         //remove highest value that caused the merge.
400                         simMatrix[row][column] = -1000.0;
401                         simMatrix[column][row] = -1000.0;
402                         
403                         //merge values in simsMatrix
404                         for (int n = 0; n < simMatrix.size(); n++)      {
405                                 //row becomes merge of 2 groups
406                                 simMatrix[row][n] = (simMatrix[row][n] + simMatrix[column][n]) / 2;
407                                 simMatrix[n][row] = simMatrix[row][n];
408                                 //delete column
409                                 simMatrix[column][n] = -1000.0;
410                                 simMatrix[n][column] = -1000.0;
411                         }
412                 }
413                 
414                 //adjust tree to make sure root to tip length is .5
415                 int root = t->findRoot();
416                 t->tree[root].setBranchLength((0.5 - t->tree[root].getLengthToLeaves()));
417                 
418                 //assemble tree
419                 t->assembleTree();
420                 
421                 if (m->control_pressed) { delete t; return 1; }
422                 
423                 //print newick file
424                 t->createNewickFile(outputFile);
425                 
426                 //delete tree
427                 delete t;
428                 
429                 if (m->control_pressed) { remove(outputFile.c_str()); outputNames.pop_back(); return 1; }
430                 
431                 return 0;
432         
433         }
434         catch(exception& e) {
435                 m->errorOut(e, "TreeGroupCommand", "createTree");
436                 exit(1);
437         }
438 }
439 /***********************************************************/
440 void TreeGroupCommand::printSims(ostream& out) {
441         try {
442                 
443                 //output column headers
444                 //out << '\t';
445                 //for (int i = 0; i < lookup.size(); i++) {     out << lookup[i]->getGroup() << '\t';           }
446                 //out << endl;
447                 
448                 
449                 for (int m = 0; m < simMatrix.size(); m++)      {
450                         //out << lookup[m]->getGroup() << '\t';
451                         for (int n = 0; n < simMatrix.size(); n++)      {
452                                 out << simMatrix[m][n] << '\t'; 
453                         }
454                         out << endl;
455                 }
456
457         }
458         catch(exception& e) {
459                 m->errorOut(e, "TreeGroupCommand", "printSims");
460                 exit(1);
461         }
462 }
463 /***********************************************************/
464 int TreeGroupCommand::makeSimsDist() {
465         try {
466                 numGroups = list->size();
467                 
468                 //initialize index
469                 index.clear();
470                 for (int g = 0; g < numGroups; g++) {   index[g] = g;   }
471                 
472                 //initialize simMatrix
473                 simMatrix.clear();
474                 simMatrix.resize(numGroups);
475                 for (int k = 0; k < simMatrix.size(); k++)      {
476                         for (int j = 0; j < simMatrix.size(); j++)      {
477                                 simMatrix[k].push_back(0.0);
478                         }
479                 }
480                 
481                 //go through sparse matrix and fill sims
482                 //go through each cell in the sparsematrix
483                 for(MatData currentCell = matrix->begin(); currentCell != matrix->end(); currentCell++){
484                         //similairity = -(distance-1)
485                         simMatrix[currentCell->row][currentCell->column] = -(currentCell->dist -1.0);   
486                         simMatrix[currentCell->column][currentCell->row] = -(currentCell->dist -1.0);   
487                         
488                         if (m->control_pressed) { return 1; }
489                         
490                 }
491
492                 return 0;
493         }
494         catch(exception& e) {
495                 m->errorOut(e, "TreeGroupCommand", "makeSimsDist");
496                 exit(1);
497         }
498 }
499
500 /***********************************************************/
501 int TreeGroupCommand::makeSimsShared() {
502         try {
503                 set<string> processedLabels;
504                 set<string> userLabels = labels;
505                 
506                 //as long as you are not at the end of the file or done wih the lines you want
507                 while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
508                         if (m->control_pressed) { for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } for(int i = 0 ; i < treeCalculators.size(); i++) {  delete treeCalculators[i]; } return 1; }
509                 
510                         if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
511                                 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
512                                 process(lookup);
513                                 
514                                 processedLabels.insert(lookup[0]->getLabel());
515                                 userLabels.erase(lookup[0]->getLabel());
516                         }
517                         
518                         if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
519                                 string saveLabel = lookup[0]->getLabel();
520                         
521                                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
522                                 lookup = input->getSharedRAbundVectors(lastLabel);
523
524                                 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
525                                 process(lookup);
526                                         
527                                 processedLabels.insert(lookup[0]->getLabel());
528                                 userLabels.erase(lookup[0]->getLabel());
529                                 
530                                 //restore real lastlabel to save below
531                                 lookup[0]->setLabel(saveLabel);
532                         }
533
534                         lastLabel = lookup[0]->getLabel();                      
535                         
536                         //get next line to process
537                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
538                         lookup = input->getSharedRAbundVectors();
539                 }
540                 
541                 if (m->control_pressed) { for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } for(int i = 0 ; i < treeCalculators.size(); i++) {  delete treeCalculators[i]; } return 1; }
542
543                 //output error messages about any remaining user labels
544                 set<string>::iterator it;
545                 bool needToRun = false;
546                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
547                         m->mothurOut("Your file does not include the label " + *it); 
548                         if (processedLabels.count(lastLabel) != 1) {
549                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
550                                 needToRun = true;
551                         }else {
552                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
553                         }
554                 }
555                 
556                 //run last label if you need to
557                 if (needToRun == true)  {
558                         for (int i = 0; i < lookup.size(); i++) {  if (lookup[i] != NULL) {             delete lookup[i]; }             } 
559                         lookup = input->getSharedRAbundVectors(lastLabel);
560
561                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
562                         process(lookup);
563                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }         
564                 }
565                 
566                 for(int i = 0 ; i < treeCalculators.size(); i++) {  delete treeCalculators[i]; }
567                 
568                 return 0;
569         }
570         catch(exception& e) {
571                 m->errorOut(e, "TreeGroupCommand", "makeSimsShared");
572                 exit(1);
573         }
574 }
575
576 /***********************************************************/
577 int TreeGroupCommand::process(vector<SharedRAbundVector*> thisLookup) {
578         try{
579                                 EstOutput data;
580                                 vector<SharedRAbundVector*> subset;
581                                 numGroups = thisLookup.size();
582                                 
583                                 //for each calculator                                                                                           
584                                 for(int i = 0 ; i < treeCalculators.size(); i++) {
585                                         //initialize simMatrix
586                                         simMatrix.clear();
587                                         simMatrix.resize(numGroups);
588                                         for (int k = 0; k < simMatrix.size(); k++)      {
589                                                 for (int j = 0; j < simMatrix.size(); j++)      {
590                                                         simMatrix[k].push_back(0.0);
591                                                 }
592                                         }
593                 
594                                         //initialize index
595                                         index.clear();
596                                         for (int g = 0; g < numGroups; g++) {   index[g] = g;   }
597                 
598                                         //create a new filename
599                                         outputFile = outputDir + m->getRootName(m->getSimpleName(globaldata->inputFileName)) + treeCalculators[i]->getName() + "." + thisLookup[0]->getLabel() + ".tre";                                
600                                         outputNames.push_back(outputFile);
601                                                                                                 
602                                         for (int k = 0; k < thisLookup.size(); k++) { 
603                                                 for (int l = k; l < thisLookup.size(); l++) {
604                                                         if (k != l) { //we dont need to similiarity of a groups to itself
605                                                                 //get estimated similarity between 2 groups
606                                                                 
607                                                                 subset.clear(); //clear out old pair of sharedrabunds
608                                                                 //add new pair of sharedrabunds
609                                                                 subset.push_back(thisLookup[k]); subset.push_back(thisLookup[l]); 
610                                                                 
611                                                                 data = treeCalculators[i]->getValues(subset); //saves the calculator outputs
612                                                 //cout << thisLookup[k]->getGroup() << '\t' << thisLookup[l]->getGroup() << '\t' << (1.0 - data[0]) << endl;
613                                                                 if (m->control_pressed) { return 1; }
614                                                                 
615                                                                 //save values in similarity matrix
616                                                                 simMatrix[k][l] = data[0];
617                                                                 simMatrix[l][k] = data[0];
618                                                         }
619                                                 }
620                                         }
621                                         
622                                         if (m->control_pressed) { return 1; }
623                                         //creates tree from similarity matrix and write out file
624                                         createTree();
625                                         
626                                         if (m->control_pressed) { return 1; }
627                                 }
628                                 
629                                 return 0;
630
631         }
632         catch(exception& e) {
633                 m->errorOut(e, "TreeGroupCommand", "process");
634                 exit(1);
635         }
636 }
637 /***********************************************************/
638
639         
640