]> git.donarmstrong.com Git - mothur.git/blob - validparameter.cpp
some bug fixes
[mothur.git] / validparameter.cpp
1 /*
2  *  validparameter.cpp
3  *  Dotur
4  *
5  *  Created by Sarah Westcott on 1/5/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "validparameter.h"
11
12 /***********************************************************************/
13
14 ValidParameters::ValidParameters() {
15         try {
16                 m = MothurOut::getInstance();
17                 initParameterRanges();
18                 commandName = "";
19         }
20         catch(exception& e) {
21                 m->errorOut(e, "ValidParameters", "ValidParameters");
22                 exit(1);
23         }
24 }
25 /***********************************************************************/
26
27 ValidParameters::ValidParameters(string c) {
28         try {
29                 m = MothurOut::getInstance();
30                 initParameterRanges();
31                 commandName = c;
32         }
33         catch(exception& e) {
34                 m->errorOut(e, "ValidParameters", "ValidParameters");
35                 exit(1);
36         }
37 }
38
39 /***********************************************************************/
40
41 ValidParameters::~ValidParameters() {}
42
43 /***********************************************************************/
44 bool ValidParameters::isValidParameter(string parameter, vector<string> cParams, string value) {
45         try {   
46                 bool valid = false;
47                 //vector<string> cParams = commandParameters[command];
48                 int numParams = cParams.size(); 
49                 for(int i = 0; i < numParams; i++) {
50                         if(cParams.at(i).compare(parameter) == 0) {
51                                 valid = true;
52                                 i = numParams;
53                         }
54                 }
55                 if(!valid) {
56                         m->mothurOut(parameter + " is not a valid parameter."); m->mothurOutEndLine();
57                         m->mothurOut("The valid parameters are: ");
58                         for(int i = 0; i < numParams-1; i++)
59                                 m->mothurOut(cParams.at(i) + ", ");
60                         m->mothurOut("and " + cParams.at(numParams-1) + ".\n");
61                         return false;
62                 }
63                 
64                 if(parameterRanges.count(parameter) != 1)
65                         return true;
66         
67                 int pVal;
68                 double piSentinel = 3.14159;
69                 vector<string> range = parameterRanges[parameter];
70                 
71                 vector<string> values;
72                 splitAtDash(value, values);
73                 
74                 for(int i = 0; i < values.size(); i++) {
75                         value = values.at(i);
76                         valid = convertTest(value, pVal);
77                 
78                         if(!valid)
79                                 return false;
80                         
81                         
82                         
83                         /********************************************************************************************************
84                                    Special Cases
85                         *********************************************************************************************************/
86                         
87                         if(parameter.compare("precision") == 0) {
88                                 double logNum = log10((double)pVal);
89                                 double diff = (double)((int)logNum - logNum);
90                                 if(diff != 0) {
91                                         m->mothurOut("The precision parameter can only take powers of 10 as a value (e.g. 10,1000,1000, etc.)\n");
92                                         return false;
93                                 }
94                         }
95                         
96                         /************************************************************************************************************/
97                         
98                         
99                         
100                         double a,b,c,d,e;
101                         
102                         if(range.at(1).compare("NA") == 0)
103                                 a = piSentinel;
104                         else
105                                 a = atoi(range.at(1).c_str()); 
106                                 
107                         if(range.at(3).compare("NA") == 0)
108                                 b = piSentinel;
109                         else
110                                 b = atoi(range.at(3).c_str()); 
111                                                 
112                         if(range.at(4).compare("between") == 0)
113                                 c = 0;
114                         else if(range.at(4).compare("only") == 0)
115                                 c = 1;
116                         else {
117                                 m->mothurOut("The range can only be 'between' or 'only' the bounding numbers.\n");
118                                 return false;
119                         }
120                         
121                         if(range.at(0).compare(">") == 0)
122                                 d = 0;
123                         else if(range.at(0).compare(">=") == 0 || range[3].compare("=>") == 0)
124                                 d = 1;
125                         else {
126                                 m->mothurOut("The parameter value can only be '>', '>=', or '=>' the lower bounding number.\n");
127                                 return false;
128                         }
129                         
130                         if(range.at(2).compare("<") == 0)
131                                 e = 0;
132                         else if(range.at(2).compare("<=") == 0 || range[4].compare("=<") == 0)
133                                 e = 1;
134                         else {
135                                 m->mothurOut("The parameter value can only be '<', '<=', or '=<' the upper bounding number.\n");
136                                 return false;
137                         }
138                         
139                         bool a0 = pVal > a;
140                         bool a1 = pVal >= a;
141                         bool b0 = pVal < b;
142                         bool b1 = pVal <= b;
143                         
144                         if(c != 1) {
145                                 if(a != piSentinel && b == piSentinel) {
146                                         if(d == 0)
147                                                 valid = a0;
148                                         else
149                                                 valid = a1;
150                                 }
151                                 else if(a == piSentinel && b != piSentinel) {
152                                         if(e == 0)
153                                                 valid = b0;
154                                         else
155                                                 valid = b1;
156                                 }
157                                 else {
158                                         if(d == 0 && e == 0)
159                                                 valid = (a0 && b0);
160                                         else if(d == 0 && e == 1)
161                                                 valid = (a0 && b1);
162                                         else if(d == 1 && e == 0)
163                                                 valid = (a1 && b0);
164                                         else
165                                                 valid = (a1 && b1);
166                                 }
167                         }
168                         else {
169                                 if(a != piSentinel && b == piSentinel)
170                                         valid = (pVal == a);
171                                 else if(a == piSentinel && b != piSentinel)
172                                         valid = (pVal == b);
173                                 else
174                                         valid = (pVal == a || pVal == b);
175                         }
176                         
177                         
178                         if(!valid) {
179                                 m->mothurOut("The '" + parameter + "' parameter needs to be ");
180                                 if(c == 1)
181                                         m->mothurOut("either '" + toString(a) + "' or '" + toString(b) + "'.\n");
182                                 else {
183                                         if(a != piSentinel) {
184                                                 m->mothurOut(">");
185                                                 if(d != 0)
186                                                         m->mothurOut("=");
187                                                 m->mothurOut(" '" + toString(a) + "'");
188                                         }
189                                         if(b == piSentinel)
190                                                 m->mothurOut( "'.\n");
191                                         else if(a != piSentinel)
192                                                 m->mothurOut(" and ");
193                                         if(b != piSentinel) {
194                                                 m->mothurOut("<");
195                                                 if(e != 0)
196                                                         m->mothurOut("=");
197                                                 m->mothurOut(" '" + toString(b) + "'.\n");
198                                         }
199                                 }
200                                 return false;
201                         }
202                 }
203                 return true;
204         }
205         catch(exception& e) {
206                 m->errorOut(e, "ValidParameters", "isValidParameters");
207                 exit(1);
208         }
209 }
210 /*******************************************************/
211
212 /******************************************************/
213
214 string ValidParameters::validFile(map<string, string>& container, string parameter, bool isFile) {
215         try {
216                 int ableToOpen;
217                 ifstream in;
218                 map<string, string>::iterator it;
219                 
220                 it = container.find(parameter);
221                 if(it != container.end()){ //no parameter given
222
223                         if(isFile == true) {
224                         
225                         #ifdef USE_MPI  
226                                 int pid, processors;
227                                 MPI_Status status;
228                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
229                                 MPI_Comm_size(MPI_COMM_WORLD, &processors);
230                                 
231                                 if (commandName == "") { processors = 1; }
232                                 
233                                 if (pid == 0) {
234                         #endif
235
236                                 ableToOpen = openInputFile(it->second, in, "noerror");
237                                 
238                                 //if you can't open it, try default location
239                                 if (ableToOpen == 1) {
240                                         if (m->getDefaultPath() != "") { //default path is set
241                                                 string tryPath = m->getDefaultPath() + getSimpleName(it->second);
242                                                 m->mothurOut("Unable to open " + it->second + ". Trying default " + tryPath); m->mothurOutEndLine();
243                                                 ableToOpen = openInputFile(tryPath, in, "noerror");
244                                                 container[parameter] = tryPath;
245                                         }
246                                 }
247                                 
248                                 in.close();
249
250                         #ifdef USE_MPI  
251                                         for(int i = 1; i < processors; i++) { 
252                                                 MPI_Send(&ableToOpen, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
253                                                 
254                                                 int length = container[parameter].length();
255                                                 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
256                                                 MPI_Send(&(container[parameter][0]), length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
257         
258                                         }
259                                 }else {
260                                         MPI_Recv(&ableToOpen, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
261                                         
262                                         int length;
263                                         MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
264                                         //recieve container
265                                         char* tempBuf = new char[length];
266                                         MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
267                                         
268                                         container[parameter] = tempBuf;
269                                         if (container[parameter].length() > length) { container[parameter] = container[parameter].substr(0, length);  }
270                                         delete tempBuf; 
271                                 }
272                                 
273                         #endif
274                         
275                                 if (ableToOpen == 1) { 
276                                         m->mothurOut("Unable to open " + container[parameter]); m->mothurOutEndLine();
277                                         return "not open"; 
278                                 }
279                         }
280                 }else { return "not found"; }
281                 
282                 return it->second;
283         
284         }
285         catch(exception& e) {
286                 m->errorOut(e, "ValidParameters", "validFile");
287                 exit(1);
288         }
289 }
290
291 /***********************************************************************/
292
293 /***********************************************************************/
294 void ValidParameters::initParameterRanges() {
295         try {   
296                 int rangeSize = 5;
297
298                 /**************************************************************************************************************
299                         {">=" or "=>" or ">" if the value should be greater than or equal to or just greater than the lower bound,
300                     A number representing the lower bound ("NA" if there is no lower bound), 
301                    "<=" or "=<" or "<" if the value shoud be less than or equal to or just less than the upper bound,
302                     A number representing the upper bound ("NA" if there is no lower bound),
303                    "between" if between lower and upper bounds or "only" if exactly one of the bounds};
304                    
305                    # = parameter
306                    # (>, >=) lower bound, # (<, <=) upperbound, # should be (between, only) lower and upper bounds.
307                    ***********************************************************************************************************/
308                 
309                 string precisionArray[] = {">=","10", "<","NA", "between"};
310                 parameterRanges["precision"] = addParameters(precisionArray, rangeSize);
311                 
312                 string itersArray[] = {">=","10", "<","NA", "between"};
313                 parameterRanges["iters"] = addParameters(itersArray, rangeSize);
314
315                 string abundArray[] = {">=","5", "<","NA", "between"};
316                 parameterRanges["abund"] = addParameters(abundArray, rangeSize);
317                 
318                 string softArray[] = {">=","0", "<=","100", "between"};
319                 parameterRanges["soft"] = addParameters(softArray, rangeSize);
320                 
321                 string sizeArray[] = {">=","1", "<","NA", "between"};
322                 parameterRanges["size"] = addParameters(sizeArray, rangeSize);
323         }
324         catch(exception& e) {
325                 m->errorOut(e, "ValidParameters", "initParameterRanges");
326                 exit(1);
327         }
328 }
329
330 /***********************************************************************/
331
332 /***********************************************************************/
333 vector<string> ValidParameters::addParameters(string parameters[], int size) {
334         try {   
335                 vector<string> pVector (parameters, parameters+size); 
336                 return pVector;
337         }
338         catch(exception& e) {
339                 m->errorOut(e, "ValidParameters", "addParameters");
340                 exit(1);
341         }
342 }
343