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