]> git.donarmstrong.com Git - mothur.git/blob - clustersplitcommand.cpp
cluster.split command
[mothur.git] / clustersplitcommand.cpp
1 /*
2  *  clustersplitcommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 5/19/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "clustersplitcommand.h"
11 #include "readcluster.h"
12 #include "splitmatrix.h"
13 #include "readphylip.h"
14 #include "readcolumn.h"
15 #include "readmatrix.hpp"
16 #include "inputdata.h"
17
18 //**********************************************************************************************************************
19 //This function checks to make sure the cluster command has no errors and then clusters based on the method chosen.
20 ClusterSplitCommand::ClusterSplitCommand(string option)  {
21         try{
22                 globaldata = GlobalData::getInstance();
23                 abort = false;
24                 
25                 //allow user to run help
26                 if(option == "help") { help(); abort = true; }
27                 
28                 else {
29                         //valid paramters for this command
30                         string Array[] =  {"phylip","column","name","cutoff","precision","method","showabund","timing","hard","processors","splitcutoff","outputdir","inputdir"};
31                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
32                         
33                         OptionParser parser(option);
34                         map<string,string> parameters = parser.getParameters();
35                         
36                         ValidParameters validParameter;
37                 
38                         //check to make sure all parameters are valid for command
39                         map<string,string>::iterator it;
40                         for (it = parameters.begin(); it != parameters.end(); it++) { 
41                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {
42                                         abort = true;
43                                 }
44                         }
45                         
46                         globaldata->newRead();
47                         
48                         //if the user changes the output directory command factory will send this info to us in the output parameter 
49                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
50                         
51                                 //if the user changes the input directory command factory will send this info to us in the output parameter 
52                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
53                         if (inputDir == "not found"){   inputDir = "";          }
54                         else {
55                                 string path;
56                                 it = parameters.find("phylip");
57                                 //user has given a template file
58                                 if(it != parameters.end()){ 
59                                         path = hasPath(it->second);
60                                         //if the user has not given a path then, add inputdir. else leave path alone.
61                                         if (path == "") {       parameters["phylip"] = inputDir + it->second;           }
62                                 }
63                                 
64                                 it = parameters.find("column");
65                                 //user has given a template file
66                                 if(it != parameters.end()){ 
67                                         path = hasPath(it->second);
68                                         //if the user has not given a path then, add inputdir. else leave path alone.
69                                         if (path == "") {       parameters["column"] = inputDir + it->second;           }
70                                 }
71                                 
72                                 it = parameters.find("name");
73                                 //user has given a template file
74                                 if(it != parameters.end()){ 
75                                         path = hasPath(it->second);
76                                         //if the user has not given a path then, add inputdir. else leave path alone.
77                                         if (path == "") {       parameters["name"] = inputDir + it->second;             }
78                                 }
79                         }
80                         
81                         //check for required parameters
82                         phylipfile = validParameter.validFile(parameters, "phylip", true);
83                         if (phylipfile == "not open") { abort = true; }
84                         else if (phylipfile == "not found") { phylipfile = ""; }        
85                         else {  distfile = phylipfile;  format = "phylip";      }
86                         
87                         columnfile = validParameter.validFile(parameters, "column", true);
88                         if (columnfile == "not open") { abort = true; } 
89                         else if (columnfile == "not found") { columnfile = ""; }
90                         else {  distfile = columnfile; format = "column";       }
91                         
92                         namefile = validParameter.validFile(parameters, "name", true);
93                         if (namefile == "not open") { abort = true; }   
94                         else if (namefile == "not found") { namefile = ""; }
95                         
96                         if ((phylipfile == "") && (columnfile == "")) { m->mothurOut("When executing a hcluster command you must enter a phylip or a column."); m->mothurOutEndLine(); abort = true; }
97                         else if ((phylipfile != "") && (columnfile != "")) { m->mothurOut("When executing a hcluster command you must enter ONLY ONE of the following: phylip or column."); m->mothurOutEndLine(); abort = true; }
98                 
99                         if (columnfile != "") {
100                                 if (namefile == "") {  cout << "You need to provide a namefile if you are going to use the column format." << endl; abort = true; }
101                         }
102                                         
103                         //check for optional parameter and set defaults
104                         // ...at some point should added some additional type checking...
105                         //get user cutoff and precision or use defaults
106                         string temp;
107                         temp = validParameter.validFile(parameters, "precision", false);
108                         if (temp == "not found") { temp = "100"; }
109                         //saves precision legnth for formatting below
110                         length = temp.length();
111                         convert(temp, precision); 
112                         
113                         temp = validParameter.validFile(parameters, "hard", false);                     if (temp == "not found") { temp = "F"; }
114                         hard = isTrue(temp);
115                         
116                         temp = validParameter.validFile(parameters, "processors", false);       if (temp == "not found"){       temp = "1";                             }
117                         convert(temp, processors); 
118                         
119                         temp = validParameter.validFile(parameters, "cutoff", false);
120                         if (temp == "not found") { temp = "10"; }
121                         convert(temp, cutoff); 
122                         if (!hard) {    cutoff += (5 / (precision * 10.0));  }
123                         
124                         temp = validParameter.validFile(parameters, "splitcutoff", false);
125                         if (temp == "not found") { temp = "0.10"; }
126                         convert(temp, splitcutoff); 
127                         if (!hard) {    splitcutoff += (5 / (precision * 10.0));  }
128                         
129                         method = validParameter.validFile(parameters, "method", false);
130                         if (method == "not found") { method = "furthest"; }
131                         
132                         if ((method == "furthest") || (method == "nearest") || (method == "average")) { }
133                         else { m->mothurOut("Not a valid clustering method.  Valid clustering algorithms are furthest, nearest or average."); m->mothurOutEndLine(); abort = true; }
134
135                         showabund = validParameter.validFile(parameters, "showabund", false);
136                         if (showabund == "not found") { showabund = "T"; }
137
138                         timing = validParameter.validFile(parameters, "timing", false);
139                         if (timing == "not found") { timing = "F"; }
140                         
141                 }
142         }
143         catch(exception& e) {
144                 m->errorOut(e, "ClusterSplitCommand", "ClusterSplitCommand");
145                 exit(1);
146         }
147 }
148
149 //**********************************************************************************************************************
150
151 void ClusterSplitCommand::help(){
152         try {
153                 m->mothurOut("The cluster command can only be executed after a successful read.dist command.\n");
154                 m->mothurOut("The cluster command parameter options are method, cuttoff, hard, precision, showabund and timing. No parameters are required.\n");
155                 m->mothurOut("The cluster command should be in the following format: \n");
156                 m->mothurOut("cluster(method=yourMethod, cutoff=yourCutoff, precision=yourPrecision) \n");
157                 m->mothurOut("The acceptable cluster methods are furthest, nearest and average.  If no method is provided then furthest is assumed.\n\n");      
158         }
159         catch(exception& e) {
160                 m->errorOut(e, "ClusterSplitCommand", "help");
161                 exit(1);
162         }
163 }
164
165 //**********************************************************************************************************************
166
167 ClusterSplitCommand::~ClusterSplitCommand(){}
168
169 //**********************************************************************************************************************
170
171 int ClusterSplitCommand::execute(){
172         try {
173         
174                 if (abort == true) {    return 0;       }
175                 
176                 //****************** file prep work ******************************//
177                 
178                 //if user gave a phylip file convert to column file
179                 if (format == "phylip") {
180         
181                         ReadCluster* convert = new ReadCluster(distfile, cutoff, outputDir, false);
182                         
183                         NameAssignment* nameMap = NULL;
184                         convert->setFormat("phylip");
185                         convert->read(nameMap);
186                         
187                         if (m->control_pressed) {  delete convert;  return 0;  }
188                         
189                         distfile = convert->getOutputFile();
190                 
191                         //if no names file given with phylip file, create it
192                         ListVector* listToMakeNameFile =  convert->getListVector();
193                         if (namefile == "") {  //you need to make a namefile for split matrix
194                                 ofstream out;
195                                 namefile = phylipfile + ".names";
196                                 openOutputFile(namefile, out);
197                                 for (int i = 0; i < listToMakeNameFile->getNumBins(); i++) {
198                                         string bin = listToMakeNameFile->get(i);
199                                         out << bin << '\t' << bin << endl;
200                                 }
201                                 out.close();
202                         }
203                         delete listToMakeNameFile;
204                         delete convert;
205                 }
206                 if (m->control_pressed) { return 0; }
207                 
208                 time_t estart = time(NULL);
209                 
210                 //split matrix into non-overlapping groups
211                 SplitMatrix* split = new SplitMatrix(distfile, namefile, splitcutoff);
212                 split->split();
213                 
214                 if (m->control_pressed) { delete split; return 0; }
215                 
216                 string singletonName = split->getSingletonNames();
217                 vector< map<string, string> > distName = split->getDistanceFiles();  //returns map of distance files -> namefile sorted by distance file size
218                 delete split;
219                 
220                 m->mothurOut("It took " + toString(time(NULL) - estart) + " seconds to split the distance file."); m->mothurOutEndLine();
221                 estart = time(NULL);
222                 
223                 if (m->control_pressed) { return 0; }
224                 
225                 //****************** break up files between processes and cluster each file set ******************************//
226                 vector<string> listFileNames;
227                 set<string> labels;
228                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
229                                 if(processors == 1){
230                                         listFileNames = cluster(distName, labels); //clusters individual files and returns names of list files
231                                 }else{
232                                         vector < vector < map<string, string> > > dividedNames; //distNames[1] = vector of filenames for process 1...
233                                         dividedNames.resize(processors);
234                                         
235                                         //for each file group figure out which process will complete it
236                                         //want to divide the load intelligently so the big files are spread between processes
237                                         int count = 1;
238                                         for (int i = 0; i < distName.size(); i++) { 
239                                                 int processToAssign = (i+1) % processors; 
240                                                 if (processToAssign == 0) { processToAssign = processors; }
241                                                 
242                                                 dividedNames[(processToAssign-1)].push_back(distName[i]);
243                                         }
244                                         
245                                         //not lets reverse the order of ever other process, so we balance big files running with little ones
246                                         for (int i = 0; i < processors; i++) {
247                                                 int remainder = ((i+1) % processors);
248                                                 if (remainder) {  reverse(dividedNames[i].begin(), dividedNames[i].end());  }
249                                         }
250                                         
251                                         createProcesses(dividedNames);
252                                                         
253                                         if (m->control_pressed) { return 0; }
254
255                                         //get list of list file names from each process
256                                         for(int i=0;i<processors;i++){
257                                                 string filename = toString(processIDS[i]) + ".temp";
258                                                 ifstream in;
259                                                 openInputFile(filename, in);
260                                                 
261                                                 while(!in.eof()) {
262                                                         string tempName;
263                                                         in >> tempName; gobble(in);
264                                                         listFileNames.push_back(tempName);
265                                                 }
266                                                 in.close();
267                                                 remove((toString(processIDS[i]) + ".temp").c_str());
268                                                 
269                                                 //get labels
270                                                 filename = toString(processIDS[i]) + ".temp.labels";
271                                                 ifstream in2;
272                                                 openInputFile(filename, in2);
273                                                 
274                                                 while(!in2.eof()) {
275                                                         string tempName;
276                                                         in2 >> tempName; gobble(in);
277                                                         if (labels.count(tempName) == 0) { labels.insert(tempName); }
278                                                 }
279                                                 in2.close();
280                                                 remove((toString(processIDS[i]) + ".temp.labels").c_str());
281                                         }
282                                 }
283                 #else
284                                 listFileNames = cluster(distName, labels); //clusters individual files and returns names of list files
285                 #endif
286                 
287                 if (m->control_pressed) { for (int i = 0; i < listFileNames.size(); i++) { remove(listFileNames[i].c_str()); } return 0; }
288                 
289                 //****************** merge list file and create rabund and sabund files ******************************//
290                                 
291                 mergeLists(listFileNames, singletonName, labels);
292
293                 if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) { remove(outputNames[i].c_str()); } return 0; }
294                 
295                 m->mothurOut("It took " + toString(time(NULL) - estart) + " seconds to cluster"); m->mothurOutEndLine();
296                 
297                 m->mothurOutEndLine();
298                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
299                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
300                 m->mothurOutEndLine();
301
302                 return 0;
303         }
304         catch(exception& e) {
305                 m->errorOut(e, "ClusterSplitCommand", "execute");
306                 exit(1);
307         }
308 }
309 //**********************************************************************************************************************
310 int ClusterSplitCommand::mergeLists(vector<string> listNames, string singleton, set<string> userLabels){
311         try {
312                 if (outputDir == "") { outputDir += hasPath(distfile); }
313                 fileroot = outputDir + getRootName(getSimpleName(distfile));
314                 
315                 openOutputFile(fileroot+ tag + ".sabund",       outSabund);
316                 openOutputFile(fileroot+ tag + ".rabund",       outRabund);
317                 openOutputFile(fileroot+ tag + ".list",         outList);
318                                 
319                 outputNames.push_back(fileroot+ tag + ".sabund");
320                 outputNames.push_back(fileroot+ tag + ".rabund");
321                 outputNames.push_back(fileroot+ tag + ".list");
322                         
323                 //read in singletons
324                 ListVector* listSingle = NULL;
325                 if (singleton != "none") {
326                         ifstream in;
327                         openInputFile(singleton, in);
328                                 
329                         string firstCol, secondCol;
330                         listSingle = new ListVector();
331                         while (!in.eof()) {
332                                 in >> firstCol >> secondCol; gobble(in);
333                                 listSingle->push_back(secondCol);
334                         }
335                         in.close();
336                 }
337                 
338                 vector<float> orderFloat;
339         
340                 //go through users set and make them floats so we can sort them 
341                 for(set<string>::iterator it = userLabels.begin(); it != userLabels.end(); ++it) {
342                         float temp;
343
344                         if ((*it != "unique") && (convertTestFloat(*it, temp) == true)){
345                                 convert(*it, temp);
346                                 orderFloat.push_back(temp);
347                         }else if (*it == "unique") { orderFloat.push_back(-1.0); }
348                         else {
349                                 userLabels.erase(*it); 
350                                 it--;
351                         }
352                 }
353                 
354                 //sort order
355                 sort(orderFloat.begin(), orderFloat.end());
356
357                 vector<InputData*> inputs;
358                 vector<string> lastLabels;
359                 for (int i = 0; i < listNames.size(); i++) {
360                         InputData* input = new InputData(listNames[i], "list");
361                         inputs.push_back(input);
362                         
363                         ifstream in;
364                         openInputFile(listNames[i], in);
365                         ListVector tempList(in);
366                         lastLabels.push_back(tempList.getLabel());
367                         in.close();
368                 }
369                 
370                 ListVector* merged = NULL;
371                                 
372                 //for each label needed
373                 for(int l = 0; l < orderFloat.size(); l++){
374                         
375                         string thisLabel;
376                         if (orderFloat[l] == -1) { thisLabel = "unique"; }
377                         else { thisLabel = toString(orderFloat[l],  length-1);  } 
378         
379                         //get the list info from each file
380                         for (int k = 0; k < listNames.size(); k++) {
381         
382                                 if (m->control_pressed) {  
383                                         if (listSingle != NULL) { delete listSingle; remove(singleton.c_str());  }
384                                         for (int i = 0; i < listNames.size(); i++) {  delete inputs[i];  remove(listNames[i].c_str());  }
385                                         delete merged; merged = NULL;
386                                         return 0;
387                                 }
388                                 
389                                 ListVector* list = inputs[k]->getListVector();
390                                 
391                                 //this file has reached the end
392                                 if (list == NULL) { list = inputs[k]->getListVector(lastLabels[k], true); }     
393                                                 
394                                 float labelFloat;
395                                 if (list->getLabel() == "unique") {  labelFloat = -1.0;  }
396                                 else { convert(list->getLabel(), labelFloat); }
397
398                                 //check for missing labels
399                                 if (labelFloat > orderFloat[l]) { //you are missing the label, get the next smallest one
400                                         //if its bigger get last label, otherwise keep it
401                                         delete list;
402                                         list = inputs[k]->getListVector(lastLabels[k], true); //get last list vector to use, you actually want to move back in the file
403                                 }
404                                 lastLabels[k] = list->getLabel();
405
406                                 //is this the first file
407                                 if (merged == NULL) {  merged = new ListVector();  merged->setLabel(thisLabel); }
408                                 
409                                 for (int j = 0; j < list->getNumBins(); j++) {
410                                         merged->push_back(list->get(j));
411                                 }
412                                 
413                                 delete list;
414                         }
415                         
416                         //add in singletons
417                         for (int j = 0; j < listSingle->getNumBins(); j++) {
418                                 merged->push_back(listSingle->get(j));
419                         }
420
421                         //print to files
422                         printData(merged);
423                         
424                         delete merged; merged = NULL;
425                 }
426                 
427                 if (listSingle != NULL) { delete listSingle; remove(singleton.c_str());  }
428                 
429                 for (int i = 0; i < listNames.size(); i++) {  delete inputs[i];  remove(listNames[i].c_str());  }
430                 
431                 return 0;
432         }
433         catch(exception& e) {
434                 m->errorOut(e, "ClusterSplitCommand", "mergeLists");
435                 exit(1);
436         }
437 }
438 //**********************************************************************************************************************
439
440 void ClusterSplitCommand::printData(ListVector* oldList){
441         try {
442                 string label = oldList->getLabel();
443                 RAbundVector oldRAbund = oldList->getRAbundVector();
444                 
445                 oldRAbund.setLabel(label);
446                 if (isTrue(showabund)) {
447                         oldRAbund.getSAbundVector().print(cout);
448                 }
449                 oldRAbund.print(outRabund);
450                 oldRAbund.getSAbundVector().print(outSabund);
451         
452                 oldList->print(outList);
453         }
454         catch(exception& e) {
455                 m->errorOut(e, "ClusterSplitCommand", "printData");
456                 exit(1);
457         }
458 }
459 //**********************************************************************************************************************
460 int ClusterSplitCommand::createProcesses(vector < vector < map<string, string> > > dividedNames){
461         try {
462         
463         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
464                 int process = 0;
465                 int exitCommand = 1;
466                 processIDS.clear();
467                 
468                 //loop through and create all the processes you want
469                 while (process != processors) {
470                         int pid = fork();
471                         
472                         if (pid > 0) {
473                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
474                                 process++;
475                         }else if (pid == 0){
476                                 set<string> labels;
477                                 vector<string> listFileNames = cluster(dividedNames[process], labels);
478                                 
479                                 //write out names to file
480                                 string filename = toString(getpid()) + ".temp";
481                                 ofstream out;
482                                 openOutputFile(filename, out);
483                                 for (int j = 0; j < listFileNames.size(); j++) { out << listFileNames[j] << endl;  }
484                                 out.close();
485                                 
486                                 //print out labels
487                                 ofstream outLabels;
488                                 filename = toString(getpid()) + ".temp.labels";
489                                 openOutputFile(filename, outLabels);
490                 
491                                 for (set<string>::iterator it = labels.begin(); it != labels.end(); it++) {
492                                         outLabels << (*it) << endl;
493                                 }
494                                 outLabels.close();
495
496                                 exit(0);
497                         }else { m->mothurOut("unable to spawn the necessary processes."); m->mothurOutEndLine(); exit(0); }
498                 }
499                 
500                 //force parent to wait until all the processes are done
501                 for (int i=0;i<processors;i++) { 
502                         int temp = processIDS[i];
503                         wait(&temp);
504                 }
505                 
506                 return exitCommand;
507         #endif          
508         
509         }
510         catch(exception& e) {
511                 m->errorOut(e, "ClusterSplitCommand", "createProcesses");
512                 exit(1);
513         }
514 }
515 //**********************************************************************************************************************
516
517 vector<string> ClusterSplitCommand::cluster(vector< map<string, string> > distNames, set<string>& labels){
518         try {
519                 Cluster* cluster;
520                 SparseMatrix* matrix;
521                 ListVector* list;
522                 ListVector oldList;
523                 RAbundVector* rabund;
524                 
525                 vector<string> listFileNames;
526                 
527                 //cluster each distance file
528                 for (int i = 0; i < distNames.size(); i++) {
529                         
530                         string thisNamefile = distNames[i].begin()->second;
531                         string thisDistFile = distNames[i].begin()->first;
532                         
533                         //read in distance file
534                         globaldata->setNameFile(thisNamefile);
535                         globaldata->setColumnFile(thisDistFile); globaldata->setFormat("column");
536                         
537                         ReadMatrix* read = new ReadColumnMatrix(thisDistFile);  
538                         read->setCutoff(cutoff);
539
540                         NameAssignment* nameMap = new NameAssignment(thisNamefile);
541                         nameMap->readMap();
542                         read->read(nameMap);
543                         
544                         if (m->control_pressed) {  delete read; delete nameMap; return listFileNames; }
545                         
546                         list = read->getListVector();
547                         oldList = *list;
548                         matrix = read->getMatrix();
549                         
550                         delete read; 
551                         delete nameMap; 
552                         
553                         m->mothurOutEndLine(); m->mothurOut("Clustering " + thisDistFile); m->mothurOutEndLine();
554                 
555                         rabund = new RAbundVector(list->getRAbundVector());
556                         
557                         //create cluster
558                         if (method == "furthest")       {       cluster = new CompleteLinkage(rabund, list, matrix, cutoff, method); }
559                         else if(method == "nearest"){   cluster = new SingleLinkage(rabund, list, matrix, cutoff, method); }
560                         else if(method == "average"){   cluster = new AverageLinkage(rabund, list, matrix, cutoff, method);     }
561                         tag = cluster->getTag();
562                 
563                         if (outputDir == "") { outputDir += hasPath(thisDistFile); }
564                         fileroot = outputDir + getRootName(getSimpleName(thisDistFile));
565                         
566                         ofstream listFile;
567                         openOutputFile(fileroot+ tag + ".list", listFile);
568                 
569                         listFileNames.push_back(fileroot+ tag + ".list");
570                 
571                         time_t estart = time(NULL);
572                         
573                         float previousDist = 0.00000;
574                         float rndPreviousDist = 0.00000;
575                         
576                         oldList = *list;
577
578                         print_start = true;
579                         start = time(NULL);
580                         double saveCutoff = cutoff;
581                 
582                         while (matrix->getSmallDist() < cutoff && matrix->getNNodes() > 0){
583                 
584                                 if (m->control_pressed) { //clean up
585                                         delete matrix; delete list;     delete cluster; delete rabund;
586                                         listFile.close();
587                                         for (int i = 0; i < listFileNames.size(); i++) {        remove(listFileNames[i].c_str());       }
588                                         listFileNames.clear(); return listFileNames;
589                                 }
590                 
591                                 cluster->update(cutoff);
592         
593                                 float dist = matrix->getSmallDist();
594                                 float rndDist = roundDist(dist, precision);
595
596                                 if(previousDist <= 0.0000 && dist != previousDist){
597                                         oldList.setLabel("unique");
598                                         oldList.print(listFile);
599                                         if (labels.count("unique") == 0) {  labels.insert("unique");  }
600                                 }
601                                 else if(rndDist != rndPreviousDist){
602                                         oldList.setLabel(toString(rndPreviousDist,  length-1));
603                                         oldList.print(listFile);
604                                         if (labels.count(toString(rndPreviousDist,  length-1)) == 0) { labels.insert(toString(rndPreviousDist,  length-1)); }
605                                 }
606                 
607                                 previousDist = dist;
608                                 rndPreviousDist = rndDist;
609                                 oldList = *list;
610                         }
611
612                 
613                         if(previousDist <= 0.0000){
614                                 oldList.setLabel("unique");
615                                 oldList.print(listFile);
616                                 if (labels.count("unique") == 0) { labels.insert("unique"); }
617                         }
618                         else if(rndPreviousDist<cutoff){
619                                 oldList.setLabel(toString(rndPreviousDist,  length-1));
620                                 oldList.print(listFile);
621                                 if (labels.count(toString(rndPreviousDist,  length-1)) == 0) { labels.insert(toString(rndPreviousDist,  length-1)); }
622                         }
623                 
624                         delete matrix; delete list;     delete cluster; delete rabund; 
625                         listFile.close();
626                         
627                         if (m->control_pressed) { //clean up
628                                 for (int i = 0; i < listFileNames.size(); i++) {        remove(listFileNames[i].c_str());       }
629                                 listFileNames.clear(); return listFileNames;
630                         }
631                         
632                         remove(thisDistFile.c_str());
633                         remove(thisNamefile.c_str());
634                 }
635                 
636                                 
637                 return listFileNames;
638         
639         }
640         catch(exception& e) {
641                 m->errorOut(e, "ClusterSplitCommand", "cluster");
642                 exit(1);
643         }
644
645
646 }
647
648 //**********************************************************************************************************************