]> git.donarmstrong.com Git - mothur.git/blob - validparameter.cpp
working on pam
[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                 m->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                 
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                                 int pos = (it->second).find(".tx.");
226                                 if (pos != string::npos) { m->sharedHeaderMode = "tax"; }
227                                 else { m->sharedHeaderMode = "otu"; }
228                         
229                         #ifdef USE_MPI  
230                                 int pid, processors;
231                                 MPI_Status status;
232                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
233                                 MPI_Comm_size(MPI_COMM_WORLD, &processors);
234                                 
235                                 if (commandName == "") { processors = 1; }
236                                 
237                                 if (pid == 0) {
238                         #endif
239                                 ifstream in;
240                                 ableToOpen = m->openInputFile(it->second, in, "noerror");
241                                 in.close();
242                                 
243                                 //if you can't open it, try default location
244                                 if (ableToOpen == 1) {
245                                         if (m->getDefaultPath() != "") { //default path is set
246                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(it->second);
247                                                 m->mothurOut("Unable to open " + it->second + ". Trying default " + tryPath); m->mothurOutEndLine();
248                                                 ifstream in2;
249                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
250                                                 in2.close();
251                                                 container[parameter] = tryPath;
252                                         }
253                                 }
254                                 
255                                 //if you can't open it, try default location
256                                 if (ableToOpen == 1) {
257                                         if (m->getOutputDir() != "") { //default path is set
258                                                 string tryPath = m->getOutputDir() + m->getSimpleName(it->second);
259                                                 m->mothurOut("Unable to open " + it->second + ". Trying output directory " + tryPath); m->mothurOutEndLine();
260                                                 ifstream in2;
261                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
262                                                 container[parameter] = tryPath;
263                                                 in2.close();
264                                         }
265                                 }
266                                 
267                                 
268
269                         #ifdef USE_MPI  
270                                         for(int i = 1; i < processors; i++) { 
271                                                 MPI_Send(&ableToOpen, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
272                                                 
273                                                 int length = container[parameter].length();
274                                                 MPI_Send(&length, 1, MPI_INT, i, 2001, MPI_COMM_WORLD);
275                                                 MPI_Send(&(container[parameter][0]), length, MPI_CHAR, i, 2001, MPI_COMM_WORLD);
276         
277                                         }
278                                 }else {
279                                         MPI_Recv(&ableToOpen, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
280                                         
281                                         int length;
282                                         MPI_Recv(&length, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
283                                         //recieve container
284                                         char* tempBuf = new char[length];
285                                         MPI_Recv(&tempBuf[0], length, MPI_CHAR, 0, 2001, MPI_COMM_WORLD, &status);
286                                         
287                                         container[parameter] = tempBuf;
288                                         if (container[parameter].length() > length) { container[parameter] = container[parameter].substr(0, length);  }
289                                         delete tempBuf; 
290                                 }
291                                 
292                         #endif
293                         
294                                 if (ableToOpen == 1) { 
295                                         m->mothurOut("Unable to open " + container[parameter]); m->mothurOutEndLine();
296                                         return "not open"; 
297                                 }
298                                 
299                                 //check phylip file to make sure its really phylip and not column
300                                 if ((it->first == "phylip") && (ableToOpen != 1)) {
301                                         ifstream inPhylip;
302                                         m->openInputFile(it->second, inPhylip);
303                                                                                 
304                                         string numTest, name;
305                                         inPhylip >> numTest >> name;
306                                         inPhylip.close();
307                                         
308                                         if (!m->isContainingOnlyDigits(numTest)) { m->mothurOut("[ERROR]: expected a number and got " + numTest + ". I suspect you entered a column formatted file as a phylip file, aborting."); m->mothurOutEndLine(); return "not found"; }
309                                 }
310                 
311                 //check for blank file
312                 if (ableToOpen != 1) {
313                     if (m->isBlank(container[parameter])) {
314                         m->mothurOut("[ERROR]: " + container[parameter] + " is blank, aborting."); m->mothurOutEndLine(); return "not found"; 
315                     }
316                 }
317                     
318                         }
319                 }else { return "not found"; }
320                 
321                 return it->second;
322         
323         }
324         catch(exception& e) {
325                 m->errorOut(e, "ValidParameters", "validFile");
326                 exit(1);
327         }
328 }
329
330 /***********************************************************************/
331
332 /***********************************************************************/
333 void ValidParameters::initParameterRanges() {
334         try {   
335                 int rangeSize = 5;
336
337                 /**************************************************************************************************************
338                         {">=" or "=>" or ">" if the value should be greater than or equal to or just greater than the lower bound,
339                     A number representing the lower bound ("NA" if there is no lower bound), 
340                    "<=" or "=<" or "<" if the value shoud be less than or equal to or just less than the upper bound,
341                     A number representing the upper bound ("NA" if there is no lower bound),
342                    "between" if between lower and upper bounds or "only" if exactly one of the bounds};
343                    
344                    # = parameter
345                    # (>, >=) lower bound, # (<, <=) upperbound, # should be (between, only) lower and upper bounds.
346                    ***********************************************************************************************************/
347                 
348                 string precisionArray[] = {">=","10", "<","NA", "between"};
349                 parameterRanges["precision"] = addParameters(precisionArray, rangeSize);
350                 
351                 string itersArray[] = {">=","1", "<","NA", "between"};
352                 parameterRanges["iters"] = addParameters(itersArray, rangeSize);
353
354                 string abundArray[] = {">=","5", "<","NA", "between"};
355                 parameterRanges["abund"] = addParameters(abundArray, rangeSize);
356                 
357                 string softArray[] = {">=","0", "<=","100", "between"};
358                 parameterRanges["soft"] = addParameters(softArray, rangeSize);
359                 
360                 string sizeArray[] = {">=","1", "<","NA", "between"};
361                 parameterRanges["size"] = addParameters(sizeArray, rangeSize);
362         }
363         catch(exception& e) {
364                 m->errorOut(e, "ValidParameters", "initParameterRanges");
365                 exit(1);
366         }
367 }
368
369 /***********************************************************************/
370
371 /***********************************************************************/
372 vector<string> ValidParameters::addParameters(string parameters[], int size) {
373         try {   
374                 vector<string> pVector (parameters, parameters+size); 
375                 return pVector;
376         }
377         catch(exception& e) {
378                 m->errorOut(e, "ValidParameters", "addParameters");
379                 exit(1);
380         }
381 }
382