]> git.donarmstrong.com Git - mothur.git/blob - venncommand.cpp
added parse.fastaq command, added permute option to venn command, fixed bug with...
[mothur.git] / venncommand.cpp
1 /*
2  *  venncommand.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 3/30/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "venncommand.h"
11 #include "ace.h"
12 #include "sobs.h"
13 #include "chao1.h"
14 //#include "jackknife.h"
15 #include "sharedsobscollectsummary.h"
16 #include "sharedchao1.h"
17 #include "sharedace.h"
18 #include "nseqs.h"
19
20
21 //**********************************************************************************************************************
22
23 VennCommand::VennCommand(string option)  {
24         try {
25                 globaldata = GlobalData::getInstance();
26                 abort = false;
27                 allLines = 1;
28                 labels.clear();
29                         
30                 //allow user to run help
31                 if(option == "help") { help(); abort = true; }
32                 
33                 else {
34                         //valid paramters for this command
35                         string AlignArray[] =  {"groups","label","calc","permute", "abund","nseqs","outputdir","inputdir"};
36                         vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
37                         
38                         OptionParser parser(option);
39                         map<string,string> parameters = parser.getParameters();
40                         
41                         ValidParameters validParameter;
42                         
43                         //check to make sure all parameters are valid for command
44                         for (map<string,string>::iterator it = parameters.begin(); it != parameters.end(); it++) { 
45                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
46                         }
47                         
48                         //make sure the user has already run the read.otu command
49                         if ((globaldata->getListFile() == "") && (globaldata->getSharedFile() == "")) {
50                                 m->mothurOut("You must read a list, or a list and a group, or a shared before you can use the venn command."); m->mothurOutEndLine(); abort = true; 
51                         }
52                         
53                         //if the user changes the output directory command factory will send this info to us in the output parameter 
54                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  
55                                 outputDir = ""; 
56                                 outputDir += m->hasPath(globaldata->inputFileName); //if user entered a file with a path then preserve it       
57                         }
58
59                         //check for optional parameter and set defaults
60                         // ...at some point should added some additional type checking...
61                         label = validParameter.validFile(parameters, "label", false);                   
62                         if (label == "not found") { label = ""; }
63                         else { 
64                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
65                                 else { allLines = 1;  }
66                         }
67                         
68                         //if the user has not specified any labels use the ones from read.otu
69                         if (label == "") {  
70                                 allLines = globaldata->allLines; 
71                                 labels = globaldata->labels; 
72                         }
73                         
74                         groups = validParameter.validFile(parameters, "groups", false);                 
75                         if (groups == "not found") { groups = ""; }
76                         else { 
77                                 m->splitAtDash(groups, Groups);
78                                 globaldata->Groups = Groups;
79                         }
80                         
81                         format = globaldata->getFormat();
82                         calc = validParameter.validFile(parameters, "calc", false);                     
83                         if (calc == "not found") { 
84                                 if(format == "list") { calc = "sobs"; }
85                                 else { calc = "sharedsobs"; }
86                         }
87                         else { 
88                                  if (calc == "default")  {  
89                                         if(format == "list") { calc = "sobs"; }
90                                         else { calc = "sharedsobs"; }
91                                 }
92                         }
93                         m->splitAtDash(calc, Estimators);
94                         
95                         string temp;
96                         temp = validParameter.validFile(parameters, "abund", false);            if (temp == "not found") { temp = "10"; }
97                         convert(temp, abund); 
98                         
99                         temp = validParameter.validFile(parameters, "nseqs", false);            if (temp == "not found"){       temp = "f";                             }
100                         nseqs = m->isTrue(temp); 
101
102                         temp = validParameter.validFile(parameters, "permute", false);                  if (temp == "not found"){       temp = "f";                             }
103                         perm = m->isTrue(temp); 
104
105                         if (abort == false) {
106                                 validCalculator = new ValidCalculators();
107                 
108                                 int i;
109                                 
110                                 if (format == "list") {
111                                         for (i=0; i<Estimators.size(); i++) {
112                                                 if (validCalculator->isValidCalculator("vennsingle", Estimators[i]) == true) { 
113                                                         if (Estimators[i] == "sobs") { 
114                                                                 vennCalculators.push_back(new Sobs());
115                                                         }else if (Estimators[i] == "chao") { 
116                                                                 vennCalculators.push_back(new Chao1());
117                                                         }else if (Estimators[i] == "ace") {
118                                                                 if(abund < 5)
119                                                                         abund = 10;
120                                                                 vennCalculators.push_back(new Ace(abund));
121                                                         }
122                                                 }
123                                         }
124                                 }else {
125                                         for (i=0; i<Estimators.size(); i++) {
126                                                 if (validCalculator->isValidCalculator("vennshared", Estimators[i]) == true) { 
127                                                         if (Estimators[i] == "sharedsobs") { 
128                                                                 vennCalculators.push_back(new SharedSobsCS());
129                                                         }else if (Estimators[i] == "sharedchao") { 
130                                                                 vennCalculators.push_back(new SharedChao1());
131                                                         }else if (Estimators[i] == "sharedace") { 
132                                                                 vennCalculators.push_back(new SharedAce());
133                                                         }
134                                                 }
135                                         }
136                                 }
137                                 
138                                 //if the users entered no valid calculators don't execute command
139                                 if (vennCalculators.size() == 0) { m->mothurOut("No valid calculators given, please correct."); m->mothurOutEndLine(); abort = true;  }
140                                 else {  venn = new Venn(outputDir, nseqs);  }
141                         }
142                         
143                 }
144
145                 
146                                 
147         }
148         catch(exception& e) {
149                 m->errorOut(e, "VennCommand", "VennCommand");
150                 exit(1);
151         }
152 }
153
154 //**********************************************************************************************************************
155
156 void VennCommand::help(){
157         try {
158                 m->mothurOut("The venn command can only be executed after a successful read.otu command.\n");
159                 m->mothurOut("The venn command parameters are groups, calc, abund, nseqs, permute and label.  No parameters are required.\n");
160                 m->mothurOut("The groups parameter allows you to specify which of the groups in your groupfile you would like included in your venn diagram, you may only use a maximum of 4 groups.\n");
161                 m->mothurOut("The group names are separated by dashes. The label allows you to select what distance levels you would like a venn diagram created for, and are also separated by dashes.\n");
162                 m->mothurOut("The venn command should be in the following format: venn(groups=yourGroups, calc=yourCalcs, label=yourLabels, abund=yourAbund).\n");
163                 m->mothurOut("Example venn(groups=A-B-C, calc=sharedsobs-sharedchao, abund=20).\n");
164                 m->mothurOut("The default value for groups is all the groups in your groupfile up to 4, and all labels in your inputfile will be used.\n");
165                 m->mothurOut("The default value for calc is sobs if you have only read a list file or if you have selected only one group, and sharedsobs if you have multiple groups.\n");
166                 m->mothurOut("The default available estimators for calc are sobs, chao and ace if you have only read a list file, and sharedsobs, sharedchao and sharedace if you have read a list and group file or a shared file.\n");
167                 m->mothurOut("The nseqs parameter will output the number of sequences represented by the otus in the picture, default=F.\n");
168                 m->mothurOut("If you have more than 4 groups, the permute parameter will find all possible combos of 4 of your groups and create pictures for them, default=F.\n");
169                 m->mothurOut("The only estimators available four 4 groups are sharedsobs and sharedchao.\n");
170                 m->mothurOut("The venn command outputs a .svg file for each calculator you specify at each distance you choose.\n");
171                 m->mothurOut("Note: No spaces between parameter labels (i.e. groups), '=' and parameters (i.e.yourGroups).\n\n");
172         }
173         catch(exception& e) {
174                 m->errorOut(e, "VennCommand", "help");
175                 exit(1);
176         }
177 }
178
179
180 //**********************************************************************************************************************
181
182 VennCommand::~VennCommand(){
183         if (abort == false) {
184                 delete input; globaldata->ginput = NULL;
185                 delete read;
186                 delete venn;
187                 globaldata->sabund = NULL;
188                 delete validCalculator;
189         }
190         
191 }
192
193 //**********************************************************************************************************************
194
195 int VennCommand::execute(){
196         try {
197         
198                 if (abort == true) { return 0; }
199                 
200                 string lastLabel;
201                 vector<string> outputNames;
202                 
203                 if (format == "sharedfile") {
204                         //you have groups
205                         read = new ReadOTUFile(globaldata->inputFileName);      
206                         read->read(&*globaldata); 
207                         
208                         input = globaldata->ginput;
209                         lookup = input->getSharedRAbundVectors();
210                         lastLabel = lookup[0]->getLabel();
211                         
212                         if ((lookup.size() > 4) && (perm)) { combosOfFour = findCombinations(lookup.size()); }
213                 }else if (format == "list") {
214                         //you are using just a list file and have only one group
215                         read = new ReadOTUFile(globaldata->inputFileName);      
216                         read->read(&*globaldata); 
217                 
218                         sabund = globaldata->sabund;
219                         lastLabel = sabund->getLabel();
220                         input = globaldata->ginput;
221                 }
222                 
223                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
224                 set<string> processedLabels;
225                 set<string> userLabels = labels;
226
227                 if (format != "list") { 
228                         
229                         //as long as you are not at the end of the file or done wih the lines you want
230                         while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
231                         
232                                 if (m->control_pressed) {
233                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
234                                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
235                                         globaldata->Groups.clear(); 
236                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str());  }
237                                         return 0;
238                                 }
239
240                                 if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
241                                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
242                                         processedLabels.insert(lookup[0]->getLabel());
243                                         userLabels.erase(lookup[0]->getLabel());
244                                         
245                                         if ((lookup.size() > 4) && (!perm)){
246                                                 m->mothurOut("Error: Too many groups chosen.  You may use up to 4 groups with the venn command.  I will use the first four groups in your groupfile. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
247                                                 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
248                                         
249                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
250                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
251
252                                         }else if ((lookup.size() > 4) && (perm)) {
253                                                 set< set<int> >::iterator it3;
254                                                 set<int>::iterator it2;
255                                                 for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
256                         
257                                                         set<int> poss = *it3;
258                                                         vector<SharedRAbundVector*> subset;
259                                                         for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
260                                                         
261                                                         vector<string> outfilenames = venn->getPic(subset, vennCalculators);
262                                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
263                                                 }               
264                                         }else {
265                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
266                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
267                                         }                                       
268                                 }
269                                 
270                                 if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
271                                         string saveLabel = lookup[0]->getLabel();
272                                         
273                                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
274                                         lookup = input->getSharedRAbundVectors(lastLabel);
275
276                                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
277                                         processedLabels.insert(lookup[0]->getLabel());
278                                         userLabels.erase(lookup[0]->getLabel());
279
280                                         if ((lookup.size() > 4) && (!perm)){
281                                                 m->mothurOut("Error: Too many groups chosen.  You may use up to 4 groups with the venn command.  I will use the first four groups in your groupfile. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
282                                                 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
283                                         
284                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
285                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
286
287                                         }else if ((lookup.size() > 4) && (perm)) {
288                                                 set< set<int> >::iterator it3;
289                                                 set<int>::iterator it2;
290                                                 for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
291                         
292                                                         set<int> poss = *it3;
293                                                         vector<SharedRAbundVector*> subset;
294                                                         for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
295                                                         
296                                                         vector<string> outfilenames = venn->getPic(subset, vennCalculators);
297                                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
298                                                 }               
299                                         }else {
300                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
301                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
302                                         }
303                                                                                 
304                                         //restore real lastlabel to save below
305                                         lookup[0]->setLabel(saveLabel);
306                                 }
307                                 
308                                 
309                                 lastLabel = lookup[0]->getLabel();      
310                                                 
311                                 //get next line to process
312                                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
313                                 lookup = input->getSharedRAbundVectors();
314                         }
315                         
316                         if (m->control_pressed) {
317                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
318                                         globaldata->Groups.clear(); 
319                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str());  }
320                                         return 0;
321                         }
322
323                         
324                         //output error messages about any remaining user labels
325                         set<string>::iterator it;
326                         bool needToRun = false;
327                         for (it = userLabels.begin(); it != userLabels.end(); it++) {  
328                                 m->mothurOut("Your file does not include the label " + *it); 
329                                 if (processedLabels.count(lastLabel) != 1) {
330                                         m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
331                                         needToRun = true;
332                                 }else {
333                                         m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
334                                 }
335                         }
336                 
337                         //run last label if you need to
338                         if (needToRun == true)  {
339                                         for (int i = 0; i < lookup.size(); i++) {  if (lookup[i] != NULL) {     delete lookup[i]; }  } 
340                                         lookup = input->getSharedRAbundVectors(lastLabel);
341
342                                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
343                                         processedLabels.insert(lookup[0]->getLabel());
344                                         userLabels.erase(lookup[0]->getLabel());
345
346                                         if ((lookup.size() > 4) && (!perm)){
347                                                 m->mothurOut("Error: Too many groups chosen.  You may use up to 4 groups with the venn command.  I will use the first four groups in your groupfile. If you set perm=t, I will find all possible combos of 4 groups."); m->mothurOutEndLine();
348                                                 for (int i = lookup.size(); i > 4; i--) { lookup.pop_back(); } //no memmory leak because pop_back calls destructor
349                                         
350                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
351                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
352
353                                         }else if ((lookup.size() > 4) && (perm)) {
354                                                 set< set<int> >::iterator it3;
355                                                 set<int>::iterator it2;
356                                                 for (it3 = combosOfFour.begin(); it3 != combosOfFour.end(); it3++) {  
357                         
358                                                         set<int> poss = *it3;
359                                                         vector<SharedRAbundVector*> subset;
360                                                         for (it2 = poss.begin(); it2 != poss.end(); it2++) {   subset.push_back(lookup[*it2]);   }
361                                                         
362                                                         vector<string> outfilenames = venn->getPic(subset, vennCalculators);
363                                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
364                                                 }               
365                                         }else {
366                                                 vector<string> outfilenames = venn->getPic(lookup, vennCalculators);
367                                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
368                                         }
369                                         
370                                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
371                         }
372                 
373
374                         //reset groups parameter
375                         globaldata->Groups.clear();  
376                         
377                         if (m->control_pressed) {
378                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
379                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str());  }
380                                         return 0;
381                         }
382
383                         
384                 }else{
385                 
386                         while((sabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
387                         
388                                 if (m->control_pressed) {
389                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
390                                         delete sabund;
391                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str());  }
392                                         return 0;
393                                 }
394                 
395                                 if(allLines == 1 || labels.count(sabund->getLabel()) == 1){                     
396         
397                                         m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
398                                         vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
399                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
400
401                                         
402                                         processedLabels.insert(sabund->getLabel());
403                                         userLabels.erase(sabund->getLabel());
404                                 }
405                                 
406                                 if ((m->anyLabelsToProcess(sabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
407                                         string saveLabel = sabund->getLabel();
408                                 
409                                         delete sabund;
410                                         sabund = input->getSAbundVector(lastLabel);
411                                         
412                                         m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
413                                         vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
414                                         for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
415
416                                         
417                                         processedLabels.insert(sabund->getLabel());
418                                         userLabels.erase(sabund->getLabel());
419                                         
420                                         //restore real lastlabel to save below
421                                         sabund->setLabel(saveLabel);
422                                 }               
423                                 
424                                 lastLabel = sabund->getLabel();         
425                                 
426                                 delete sabund;
427                                 sabund = input->getSAbundVector();
428                         }
429                         
430                         if (m->control_pressed) {
431                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
432                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str());  }
433                                         return 0;
434                         }
435                         
436                         //output error messages about any remaining user labels
437                         set<string>::iterator it;
438                         bool needToRun = false;
439                         for (it = userLabels.begin(); it != userLabels.end(); it++) {  
440                                 m->mothurOut("Your file does not include the label " + *it); 
441                                 if (processedLabels.count(lastLabel) != 1) {
442                                         m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
443                                         needToRun = true;
444                                 }else {
445                                         m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
446                                 }
447                         }
448                 
449                         //run last label if you need to
450                         if (needToRun == true)  {
451                                 if (sabund != NULL) {   delete sabund;  }
452                                 sabund = input->getSAbundVector(lastLabel);
453                                         
454                                 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
455                                 vector<string> outfilenames = venn->getPic(sabund, vennCalculators);
456                                 for(int i = 0; i < outfilenames.size(); i++) { if (outfilenames[i] != "control" ) { outputNames.push_back(outfilenames[i]); }  }
457
458                                 delete sabund;
459                                         
460                         }
461                         
462                         if (m->control_pressed) {
463                                         for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
464                                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str());  }
465                                         return 0;
466                         }
467                 }
468                 
469                 for (int i = 0; i < vennCalculators.size(); i++) {      delete vennCalculators[i];      }
470                 
471                 m->mothurOutEndLine();
472                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
473                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
474                 m->mothurOutEndLine();
475
476                 
477                 return 0;
478         }
479         catch(exception& e) {
480                 m->errorOut(e, "VennCommand", "execute");
481                 exit(1);
482         }
483 }
484 //**********************************************************************************************************************
485 //returns a vector of sets containing the 4 group combinations
486 set< set<int> > VennCommand::findCombinations(int lookupSize){
487         try {
488                 set< set<int> > combos;
489                 
490                 set<int> possibles;
491                 for (int i = 0; i < lookupSize; i++) {  possibles.insert(i);  }
492                 
493                 getCombos(possibles, combos);
494                 
495                 return combos;
496                 
497         }
498         catch(exception& e) {
499                 m->errorOut(e, "VennCommand", "findCombinations");
500                 exit(1);
501         }
502 }
503 //**********************************************************************************************************************
504 //recusively finds combos of 4
505 int VennCommand::getCombos(set<int> possibles, set< set<int> >& combos){
506         try {
507                 
508                 if (possibles.size() == 4) { //done
509                         if (combos.count(possibles) == 0) { //no dups
510                                 combos.insert(possibles);
511                         }
512                 }else { //we still have work to do
513                         set<int>::iterator it;
514                         set<int>::iterator it2;
515                         for (it = possibles.begin(); it != possibles.end(); it++) {  
516                                 
517                                 set<int> newPossibles;
518                                 for (it2 = possibles.begin(); it2 != possibles.end(); it2++) {  //all possible combos of one length smaller
519                                         if (*it != *it2) { 
520                                                 newPossibles.insert(*it2);
521                                         }
522                                 }
523                                 getCombos(newPossibles, combos);
524                         }
525                 }
526                 
527                 return 0;
528         }
529         catch(exception& e) {
530                 m->errorOut(e, "VennCommand", "getCombos");
531                 exit(1);
532         }
533 }
534
535 //**********************************************************************************************************************