]> git.donarmstrong.com Git - mothur.git/blob - clusterdoturcommand.cpp
added [ERROR] flag if command aborts
[mothur.git] / clusterdoturcommand.cpp
1 /*
2  *  clusterdoturcommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 10/27/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "clusterdoturcommand.h"
11 #include "clusterclassic.h"
12
13 //**********************************************************************************************************************
14 vector<string> ClusterDoturCommand::getValidParameters(){       
15         try {
16                 string AlignArray[] =  {"phylip","name","hard","cutoff","precision","method","outputdir","inputdir"};
17                 vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));
18                 return myArray;
19         }
20         catch(exception& e) {
21                 m->errorOut(e, "ClusterDoturCommand", "getValidParameters");
22                 exit(1);
23         }
24 }
25 //**********************************************************************************************************************
26 ClusterDoturCommand::ClusterDoturCommand(){     
27         try {
28                 abort = true; calledHelp = true; 
29                 vector<string> tempOutNames;
30                 outputTypes["list"] = tempOutNames;
31                 outputTypes["rabund"] = tempOutNames;
32                 outputTypes["sabund"] = tempOutNames;
33         }
34         catch(exception& e) {
35                 m->errorOut(e, "ClusterDoturCommand", "ClusterCommand");
36                 exit(1);
37         }
38 }
39 //**********************************************************************************************************************
40 vector<string> ClusterDoturCommand::getRequiredParameters(){    
41         try {
42                 string Array[] =  {"phylip"};
43                 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
44                 return myArray;
45         }
46         catch(exception& e) {
47                 m->errorOut(e, "ClusterDoturCommand", "getRequiredParameters");
48                 exit(1);
49         }
50 }
51 //**********************************************************************************************************************
52 vector<string> ClusterDoturCommand::getRequiredFiles(){ 
53         try {
54                 vector<string> myArray; 
55                 return myArray;
56         }
57         catch(exception& e) {
58                 m->errorOut(e, "ClusterDoturCommand", "getRequiredFiles");
59                 exit(1);
60         }
61 }
62 //**********************************************************************************************************************
63 //This function checks to make sure the cluster command has no errors and then clusters based on the method chosen.
64 ClusterDoturCommand::ClusterDoturCommand(string option)  {
65         try{
66                 
67                 abort = false; calledHelp = false;   
68                 
69                 //allow user to run help
70                 if(option == "help") { help(); abort = true; calledHelp = true; }
71                 
72                 else {
73                         //valid paramters for this command
74                         string Array[] =  {"phylip","name","cutoff","hard","precision","method","outputdir","inputdir"};
75                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
76                         
77                         OptionParser parser(option);
78                         map<string,string> parameters = parser.getParameters();
79                         
80                         ValidParameters validParameter;
81                 
82                         //check to make sure all parameters are valid for command
83                         map<string,string>::iterator it;
84                         for (it = parameters.begin(); it != parameters.end(); it++) { 
85                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {
86                                         abort = true;
87                                 }
88                         }
89                         
90                         //if the user changes the input directory command factory will send this info to us in the output parameter 
91                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
92                         if (inputDir == "not found"){   inputDir = "";          }
93                         else {
94                                 string path;
95                                 it = parameters.find("phylip");
96                                 //user has given a template file
97                                 if(it != parameters.end()){ 
98                                         path = m->hasPath(it->second);
99                                         //if the user has not given a path then, add inputdir. else leave path alone.
100                                         if (path == "") {       parameters["phylip"] = inputDir + it->second;           }
101                                 }
102                                 
103                                 it = parameters.find("name");
104                                 //user has given a template file
105                                 if(it != parameters.end()){ 
106                                         path = m->hasPath(it->second);
107                                         //if the user has not given a path then, add inputdir. else leave path alone.
108                                         if (path == "") {       parameters["name"] = inputDir + it->second;             }
109                                 }
110
111                         }
112                         
113                         //initialize outputTypes
114                         vector<string> tempOutNames;
115                         outputTypes["list"] = tempOutNames;
116                         outputTypes["rabund"] = tempOutNames;
117                         outputTypes["sabund"] = tempOutNames;
118                 
119                         //if the user changes the output directory command factory will send this info to us in the output parameter 
120                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
121                         
122                         //check for required parameters
123                         phylipfile = validParameter.validFile(parameters, "phylip", true);
124                         if (phylipfile == "not open") { abort = true; }
125                         else if (phylipfile == "not found") { phylipfile = ""; m->mothurOut("When executing the cluster.dotur command you must enter a phylip file."); m->mothurOutEndLine(); abort = true; }   
126
127                 
128                         //check for optional parameter and set defaults
129                         namefile = validParameter.validFile(parameters, "name", true);
130                         if (namefile == "not open") { abort = true; }   
131                         else if (namefile == "not found") { namefile = ""; }
132                         
133                         string temp;
134                         temp = validParameter.validFile(parameters, "precision", false);
135                         if (temp == "not found") { temp = "100"; }
136                         //saves precision legnth for formatting below
137                         length = temp.length();
138                         convert(temp, precision); 
139                         
140                         temp = validParameter.validFile(parameters, "cutoff", false);
141                         if (temp == "not found") { temp = "10"; }
142                         convert(temp, cutoff); 
143                         cutoff += (5 / (precision * 10.0));  
144                         
145                         temp = validParameter.validFile(parameters, "hard", false);                     if (temp == "not found") { temp = "F"; }
146                         hard = m->isTrue(temp);
147                         
148                         method = validParameter.validFile(parameters, "method", false);
149                         if (method == "not found") { method = "furthest"; }
150                         
151                         if ((method == "furthest") || (method == "nearest") || (method == "average") || (method == "weighted")) { 
152                                 if (method == "furthest") { tag = "fn"; }
153                                 else if (method == "nearest") { tag = "nn"; }
154                                 else if (method == "average") { tag = "an"; }
155                                 else if (method == "weighted") { tag = "wn"; }
156                         }else { m->mothurOut("Not a valid clustering method.  Valid clustering algorithms are furthest, nearest, average, weighted."); m->mothurOutEndLine(); abort = true; }
157                 }
158         }
159         catch(exception& e) {
160                 m->errorOut(e, "ClusterDoturCommand", "ClusterCommand");
161                 exit(1);
162         }
163 }
164
165 //**********************************************************************************************************************
166
167 void ClusterDoturCommand::help(){
168         try {
169                 m->mothurOut("The cluster.classic command clusters using the algorithm from dotur. \n");
170                 m->mothurOut("The cluster.classic command parameter options are phylip, name, method, cuttoff, hard, precision. Phylip is required.\n");
171                 m->mothurOut("The cluster.classic command should be in the following format: \n");
172                 m->mothurOut("cluster.classic(phylip=yourDistanceMatrix, method=yourMethod, cutoff=yourCutoff, precision=yourPrecision) \n");
173                 m->mothurOut("The acceptable cluster methods are furthest, nearest, weighted and average.  If no method is provided then furthest is assumed.\n\n");    
174
175         }
176         catch(exception& e) {
177                 m->errorOut(e, "ClusterDoturCommand", "help");
178                 exit(1);
179         }
180 }
181
182 //**********************************************************************************************************************
183
184 ClusterDoturCommand::~ClusterDoturCommand(){}
185
186 //**********************************************************************************************************************
187
188 int ClusterDoturCommand::execute(){
189         try {
190         
191                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
192                 
193                 if(namefile != ""){     
194                         nameMap = new NameAssignment(namefile);
195                         nameMap->readMap();
196                 }else{
197                         nameMap = NULL;
198                 }
199                 
200                 //reads phylip file storing data in 2D vector, also fills list and rabund
201                 ClusterClassic* cluster = new ClusterClassic(cutoff, method);
202                 cluster->readPhylipFile(phylipfile, nameMap);
203                 
204                 if (m->control_pressed) { delete cluster; delete list; delete rabund; return 0; }
205                 
206                 list = cluster->getListVector();
207                 rabund = cluster->getRAbundVector();
208                                                 
209                 if (outputDir == "") { outputDir += m->hasPath(phylipfile); }
210                 fileroot = outputDir + m->getRootName(m->getSimpleName(phylipfile));
211                         
212                 m->openOutputFile(fileroot+ tag + ".sabund",    sabundFile);
213                 m->openOutputFile(fileroot+ tag + ".rabund",    rabundFile);
214                 m->openOutputFile(fileroot+ tag + ".list",              listFile);
215                                 
216                 outputNames.push_back(fileroot+ tag + ".sabund"); outputTypes["sabund"].push_back(fileroot+ tag + ".sabund");
217                 outputNames.push_back(fileroot+ tag + ".rabund"); outputTypes["rabund"].push_back(fileroot+ tag + ".rabund");
218                 outputNames.push_back(fileroot+ tag + ".list"); outputTypes["list"].push_back(fileroot+ tag + ".list");
219                 
220                 float previousDist = 0.00000;
221                 float rndPreviousDist = 0.00000;
222                 oldRAbund = *rabund;
223                 oldList = *list;
224
225                 //double saveCutoff = cutoff;
226                 
227                 int estart = time(NULL);
228         
229                 while ((cluster->getSmallDist() < cutoff) && (cluster->getNSeqs() > 1)){
230                         if (m->control_pressed) { delete cluster; delete list; delete rabund; sabundFile.close();rabundFile.close();listFile.close();  for (int i = 0; i < outputNames.size(); i++) {   remove(outputNames[i].c_str());         } outputTypes.clear();  return 0;  }
231                 
232                         cluster->update(cutoff);
233         
234                         float dist = cluster->getSmallDist();
235                         float rndDist;
236                         if (hard) {
237                                 rndDist = m->ceilDist(dist, precision); 
238                         }else{
239                                 rndDist = m->roundDist(dist, precision); 
240                         }
241
242                         if(previousDist <= 0.0000 && dist != previousDist){
243                                 printData("unique");
244                         }
245                         else if(rndDist != rndPreviousDist){
246                                 printData(toString(rndPreviousDist,  length-1));
247                         }
248                 
249                         previousDist = dist;
250                         rndPreviousDist = rndDist;
251                         oldRAbund = *rabund;
252                         oldList = *list;
253                 }
254         
255                 if(previousDist <= 0.0000){
256                         printData("unique");
257                 }
258                 else if(rndPreviousDist<cutoff){
259                         printData(toString(rndPreviousDist, length-1));
260                 }
261                                         
262                 sabundFile.close();
263                 rabundFile.close();
264                 listFile.close();
265                 
266                 delete cluster; delete nameMap; delete list; delete rabund;
267         
268                 //if (saveCutoff != cutoff) { 
269                 //      if (hard)       {  saveCutoff = m->ceilDist(saveCutoff, precision);     }
270                 //      else            {       saveCutoff = m->roundDist(saveCutoff, precision);  }
271                 //      m->mothurOut("changed cutoff to " + toString(cutoff)); m->mothurOutEndLine(); 
272                 //}
273                 
274                 m->mothurOutEndLine();
275                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
276                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
277                 m->mothurOutEndLine();
278
279                 m->mothurOut("It took " + toString(time(NULL) - estart) + " seconds to cluster"); m->mothurOutEndLine();
280
281                 return 0;
282         }
283         catch(exception& e) {
284                 m->errorOut(e, "ClusterDoturCommand", "execute");
285                 exit(1);
286         }
287 }
288
289 //**********************************************************************************************************************
290
291 void ClusterDoturCommand::printData(string label){
292         try {
293         
294                 oldRAbund.setLabel(label);
295                 oldRAbund.print(rabundFile);
296                 oldRAbund.getSAbundVector().print(sabundFile);
297                 
298                 oldRAbund.getSAbundVector().print(cout);
299                 
300                 oldList.setLabel(label);
301                 oldList.print(listFile);
302         }
303         catch(exception& e) {
304                 m->errorOut(e, "ClusterDoturCommand", "printData");
305                 exit(1);
306         }
307 }
308 //**********************************************************************************************************************