NIREP
|
00001 /* +-----------+ 00002 | Libraries | 00003 +-----------+ */ 00004 #include <algorithm> 00005 #include "EvaluatorList.h" 00006 #include "NIREPDefinitions.h" 00007 00008 00009 /* +----------------+ 00010 | Public Methods | 00011 +----------------+ */ 00012 00013 /* 00014 function: EvaluatorList 00015 purpose: Initialize task with empty, error 00016 */ 00017 EvaluatorList::EvaluatorList() 00018 { 00019 this->error = false; 00020 this->SetEvaluatorTask("#", "empty()"); 00021 this->SetEvaluatorTask("!", "error()"); 00022 this->SetVarList(new VariableList()); 00023 } 00024 00025 00026 /* 00027 function: EvaluatorList 00028 purpose: Initialize task with empty, error. Reads in evaluator list 00029 00030 input: fileName std::string path to the evaluator list description 00031 */ 00032 EvaluatorList::EvaluatorList(const std::string& fileName) 00033 { 00034 this->error = false; 00035 VariableList* vList = new VariableList(fileName); 00036 00037 this->SetEvaluatorTask("#", "empty()"); 00038 this->SetEvaluatorTask("!", "error()"); 00039 this->SetVarList(vList); 00040 error = this->Read(fileName); 00041 } 00042 00043 EvaluatorList::EvaluatorList(const std::string& fileName, VariableList* vList) 00044 { 00045 this->error = false; 00046 this->SetEvaluatorTask("#", "empty()"); 00047 this->SetEvaluatorTask("!", "error()"); 00048 this->SetVarList(vList); 00049 error = this->Read(fileName); 00050 } 00051 00052 EvaluatorList::EvaluatorList(VariableList* vList) 00053 { 00054 this->error = false; 00055 this->SetEvaluatorTask("#", "empty()"); 00056 this->SetEvaluatorTask("!", "error()"); 00057 this->SetVarList(vList); 00058 } 00059 00060 /* 00061 function: ~EvaluatorList 00062 purpose: class destructor, destroying references to pointers 00063 */ 00064 EvaluatorList::~EvaluatorList() 00065 { 00066 vars = NULL; 00067 } 00068 00069 /* 00070 function: Read 00071 purpose: To read in the evaluator list 00072 00073 input: fileName std::string path to the evaluator list description 00074 00075 output: updated task 00076 */ 00077 bool EvaluatorList::Read(const std::string& fileName) 00078 { 00079 this->task.clear(); 00080 this->taskFullName.clear(); 00081 std::ifstream file (fileName.c_str()); 00082 int list = 0; 00083 00084 if (file.is_open()) 00085 { 00086 // Create a list of Evaluator commands 00087 EvaluatorCmdList eCmds; 00088 EvaluatorCmdList::iterator iter; 00089 for(iter=EvalCmd.begin(); iter != EvalCmd.end(); ++iter){ 00090 eCmds[iter->second] = iter->second; 00091 } 00092 00093 std::string line; 00094 00095 while (! file.eof() ) // loop through the file 00096 { 00097 getline (file,line); 00098 // Convert line to lower case for comparison 00099 std::transform(line.begin(), line.end(), line.begin(), tolower); 00100 00101 if(list == 0) // check to see if the evaluator list has started 00102 { 00103 // if we find the start designator, update the flag 00104 if(!line.compare("begin evaluatorlist")) 00105 { 00106 list = EVALUATORLIST; 00107 } 00108 } 00109 // we're in the evaluator list 00110 else if(list == EVALUATORLIST) 00111 { 00112 // check to see if it's over 00113 if(!line.compare("end evaluatorlist")) 00114 { 00115 list=0; 00116 } 00117 else if(line.compare("") != 0) // we're still in the evaluator list \o/ 00118 { 00119 // extract the task name 00120 size_t found = line.find_first_of("="); 00121 if( found == std::string::npos ) { 00122 wxString temp(wxT("Error: Missing equal sign in command: ")); 00123 temp.Append(wxString::Format (wxT("%s"), line.c_str())); 00124 wxLogError(temp); 00125 return true; 00126 } 00127 std::string id(line, 0,found); 00128 wxString wxID(id.c_str(), wxConvUTF8); // convert to cstring 00129 wxID.Trim(); // trim right side 00130 wxID.Trim(false); // trim left side 00131 id = wxID.ToAscii(); 00132 00133 // extract the expression 00134 std::string function(line, found+1,line.length()); 00135 wxString wxFunction(function.c_str(), wxConvUTF8); 00136 wxFunction.Trim(); 00137 wxFunction.Trim(false); 00138 function = wxFunction.ToAscii(); 00139 00142 // FIX THIS SO THAT IT DOES NOT BREAK WITH EXTRA CHARACTERS AFTER THE LAST ")" such as a semicolon 00143 // THINK ABOUT COUNTING # OF OPEN AND CLOSED PARENTHESES 00146 size_t firstParentheses=function.find_first_of("("); 00147 size_t lastParentheses=function.find_first_of(")"); 00148 if( (lastParentheses+1) != function.size() ) { 00149 wxString temp(wxT("Error: Missing right parentheses in command: ")); 00150 temp.Append(wxString::Format (wxT("%s=%s"), id.c_str(), function.c_str())); 00151 wxLogError(temp); 00152 return true; 00153 } 00154 else if( firstParentheses == std::string::npos ) 00155 { 00156 wxString temp(wxT("Error: Missing left parentheses in command:")); 00157 temp.Append(wxString::Format (wxT("%s=%s"), id.c_str(), function.c_str())); 00158 wxLogError(temp); 00159 return true; 00160 } 00161 std::string type(function, 0,firstParentheses); 00162 00163 if( eCmds.find(type) == eCmds.end() ) { 00164 wxString temp(wxT("Error: Unkown evaluator command:")); 00165 temp.Append(wxString::Format (wxT("%s for %s=%s"), type.c_str() , id.c_str(), function.c_str())); 00166 wxLogError(temp); 00167 return true; 00168 } 00169 //if( evaluatorCommands.fList.find(type) == evaluatorCommands.fList.end() ) { 00170 // wxString temp = "Error: Unkown evaluator command:"; 00171 // temp.Append(wxString::Format ("%s for %s=%s", _(type.c_str()) , _(id.c_str()), _(function.c_str()))); 00172 // ::wxLogError(temp); 00173 // return true; 00174 //} 00175 00176 // std::vector<std::string> params = this->GetTaskParameters(function); 00177 00178 // std::string functionTwo = type; 00179 // functionTwo.append("("); 00180 // for (int i=0; i < (int) params.size(); i++) 00181 //{ 00182 // //std::string key = this->vars->GetVariable(params[i]); 00183 // //if (this->vars->GetVariable(params[i]).compare("$") != 0) 00184 // // params[i] = this->vars->GetVariable(params[i]); 00185 // functionTwo.append(params[i]); 00186 // functionTwo.append(","); 00187 //} 00188 // functionTwo.erase(functionTwo.end()-1); 00189 // functionTwo.append(")"); 00190 00191 // add to evaluator list 00192 //this->SetEvaluatorTask(id, functionTwo); 00193 this->SetEvaluatorTask(id, function); 00194 } 00195 } 00196 00197 } 00198 00199 file.close(); 00200 return false; 00201 } 00202 wxString temp(wxT("Error: Could not open file: ")); 00203 temp.Append(wxString::Format (wxT("%s"), fileName.c_str())); 00204 wxLogError(temp); 00205 return true; 00206 } 00207 00208 00209 00210 /* 00211 function: Write 00212 purpose: To save the evaluator list to disk 00213 00214 input: fileName std::string path to the evaluator list description 00215 00216 output: updated task 00217 */ 00218 void EvaluatorList::Write(const std::string& fileName) 00219 { 00220 } 00221 00222 00223 /* 00224 function: GetTaskParameters 00225 purpose: Retrieve the parameters for a task 00226 00227 This task retrieves the task's command parameters. For instance, for the 00228 task "_A1 = readImage(1,MRI)", this function would return the vector: 00229 [0] = 1 00230 [1] = MRI 00231 00232 input: taskName std::string the reference name of the task 00233 output: std::vector<std::string> the parameters of the task 00234 */ 00235 std::vector <std::string> EvaluatorList::GetTaskParameters(const std::string taskName) 00236 { 00237 std::string temp = taskName; 00238 std::vector<std::string> params; 00239 00240 std::string temp2 = temp.substr(temp.size()-1,1); 00241 // first, see if it is a command like readImage(1,MRI) or if it is a task like _A1 00242 //if ( ( temp2.compare(")") == 1 ) || (temp2.size() < 1) ) 00243 if ( ( temp2.compare(")") != 0 ) || temp2.empty() ) 00244 { // ex: diff(_A2, _A3) 00245 if ( this->inMap(this->task,temp) ) { 00246 // if it's in the map 00247 temp = this->task[temp]; 00248 } else // _A1 is NOT found in the map 00249 { 00250 params.push_back("#"); 00251 return params; 00252 } 00253 } 00254 00255 // first, remove the trailing parenthesis 00256 // ex: 00257 // source: viewImage(_A1,MRI) 00258 // temp: viewImage(_A1,MRI 00259 temp = temp.substr(0,temp.find_last_of(")")); 00260 00261 // then, extract the variable list 00262 // ex: 00263 // temp: viewImage(_A1,MRI 00264 // temp: _A1,MRI 00265 temp = temp.substr(temp.find_first_of("(")+1); 00266 00267 // finally, create the vector of parameters 00268 // ex: 00269 // temp: _A1, MRI 00270 // params[0]: _A1 00271 // [1]: MRI 00272 std::string delim = ","; 00273 this->StringExplode(temp, delim, ¶ms); 00274 00275 for (int i=0; i < (int) params.size(); i++) 00276 { 00277 //std::string key = this->vars->GetVariable(params[i]); 00278 if (this->vars->GetVariable(params[i]).compare("$") != 0) 00279 params[i] = this->vars->GetVariable(params[i]); 00280 } 00281 return params; 00282 } 00283 00284 /* 00285 function: GetTaskFunction 00286 purpose: retrieves the task's function 00287 00288 input: const std::string taskName with the name of the task 00289 00290 output: std::string with the function used by NIREPEvaluator::evaluate 00291 */ 00292 std::string EvaluatorList::GetTaskFunction(const std::string taskName) 00293 { 00296 // FIX THIS SO IT IS NOT SO FRAGLE. THIS CODE ASSUMES THAT THE LAST 00297 // CHARACTER OF THE TASK IS A ")". WHAT IF THERE IS A SPACE AFTERWARDS? 00300 std::string temp = taskName.substr(taskName.size()-1,1), temp2; 00301 00302 if ( ( temp.compare(")") == 1 ) || (temp.size() < 1) ) 00303 { // ex: diff(_A2, _A3) 00304 if ( this->inMap(this->task,taskName) ) // if it's in the map 00305 temp2 = this->task[taskName].substr(0,this->task[taskName].find_first_of("(")); 00306 else // _A1 is NOT found in the map 00307 { 00308 return "#"; 00309 } 00310 } 00311 else 00312 temp2 = taskName.substr(0,taskName.find_first_of("(")); 00313 return temp2 ; 00314 } 00315 00316 00317 /* 00318 function: GetTaskKeys 00319 purpose: retrieves the keys from the tasks map, as strings 00320 returns: std::vector<std::string> containing the keys (eg: _A1, _A2, etc) 00321 */ 00322 std::vector<std::string> EvaluatorList::GetTaskKeys() 00323 { 00324 std::vector<std::string> keys; 00325 00326 for(std::map<std::string, std::string>::iterator it=this->task.begin(); it!=this->task.end(); ++it) 00327 { 00328 keys.push_back(it->first); 00329 } 00330 00331 return keys; 00332 } 00333 00334 00335 /* 00336 function: GetTaskValues 00337 purpose: retrieves the values from the tasks map, as strings 00338 input: fullName bool flag to determine if the fully qualified name is returned or not. defaults to 0 (no). 00339 returns: std::vector<std::string> containing the values (eg: readImage(1,MRI), etc) 00340 */ 00341 std::vector<std::string> EvaluatorList::GetTaskValues(bool fullName) 00342 { 00343 std::vector<std::string> vals; 00344 00345 for(std::map<std::string, std::string>::iterator it=this->task.begin(); it!=this->task.end(); ++it) 00346 { 00347 if (fullName) { 00348 size_t firstParentheses= it->second.find_first_of("("); 00349 std::vector<std::string> params = this->GetTaskParameters(it->second); 00350 std::string type(it->second, 0,firstParentheses); 00351 std::string functionTwo = type; 00352 functionTwo.append("("); 00353 for (int i=0; i < (int) params.size(); i++) 00354 { 00355 //std::string key = this->vars->GetVariable(params[i]); 00356 if (this->unwrap(params[i]).compare("#") != 0) 00357 params[i] =this->unwrap(params[i]); 00358 functionTwo.append(params[i]); 00359 functionTwo.append(","); 00360 } 00361 functionTwo.erase(functionTwo.end()-1); 00362 functionTwo.append(")"); 00363 00364 vals.push_back(functionTwo); 00365 //std::string tempString = this->GetEvaluatorCommand(it->second); 00366 //if(tempString.compare("#") == 0) { 00367 // vals.push_back(it->second); 00368 //} else { 00369 // vals.push_back(tempString); 00370 //} 00371 00372 } 00373 else 00374 vals.push_back(it->second); 00375 } 00376 00377 return vals; 00378 } 00379 00380 00381 /* 00382 function: GetTasks 00383 purpose: retrieves the keys and values from the tasks map, as strings 00384 00385 inputs: 00386 keys std::vector<std::string>* containing the keys (eg: _A1, _A2, etc) 00387 vals std::vector<std::string>* containing the values (eg: readImage(1,MRI), etc) 00388 fullName bool flag to determine if the fully qualified name is returned or not. defaults to 0 (no). 00389 */ 00390 void EvaluatorList::GetTasks(std::vector<std::string> * keys, std::vector<std::string> * values, bool fullName) 00391 { 00392 *keys = this->GetTaskKeys(); 00393 *values = this->GetTaskValues(fullName); 00394 } 00395 00396 00397 00398 /* +-----------------+ 00399 | Private Methods | 00400 +-----------------+ */ 00401 00402 /* 00403 function: unwrap 00404 purpose: unwraps command strings 00405 00406 The evaluator list, eList, maps keys against functions (which take parameters 00407 of other keys) and base functions (which have parameters that don't contain keys). 00408 This unwraps those keys to their fully formed expression, eg: 00409 _A1 => readImage(1,MRI) 00410 _A2 => readImage(2,MRI) 00411 _A3 => diff(_A1, _A2) 00412 unwrap(_A3) => diff(readImage(1,MRI),readImage(2,MRI)) 00413 00414 input: source std:string containing the source command (ex: _A4) 00415 00416 output: std:string with the fully unwrapped command 00417 (ex: diff(readImage(1,MRI),readImage(2,MRI))) 00418 */ 00419 std::string EvaluatorList::unwrap(std::string source) 00420 { 00421 std::string unwrapped, // stores the result 00422 fcn; // stores the function from the parsing 00423 std::vector<std::string> params; // stores the params from the parsing 00424 00425 // if it's a readImage(1, MRI) or readCoeff(file), we don't need to unwind further 00426 if ( (source.compare("#")==0) ||( source.size() == 0 ) ) 00427 return "#"; 00428 00429 // if it's not a read function, if it contains a ), it's a function that 00430 // needs to be exploded and unwrapped 00431 //if ( source.substr(source.size(),1).compare(")") == 0 ) 00432 size_t index1 = source.find_last_of(")"); 00433 if ( index1 != std::string::npos ) 00434 { // ex: diff(_A2, _A3) 00435 fcn = this->GetTaskFunction(source); 00436 params = this->GetTaskParameters(source); 00437 00438 for (int i=0; i < (int) params.size(); i++) 00439 { 00440 //std::string key = this->vars->GetVariable(params[i]); 00441 //if (this->vars->GetVariable(params[i]).compare("$") != 0) 00442 // params[i] = this->vars->GetVariable(params[i]); 00443 if ( this->inMap(this->task, params[i]) ) 00444 params[i] = this->unwrap( params[i] ); 00445 } 00446 } 00447 else 00448 // if it's not a function or a read, it's a key in the evaluator list (eList) 00449 // and needs to be parsed if it's found, or return an error if it's not found 00450 { // ex: _A1 00451 //if ( eList.find(source) < eList.end() ) // _A1 is found in the map 00453 00454 if ( this->inMap(this->task,source) ) 00455 { 00456 fcn = this->GetTaskFunction(task[source]); 00457 params = this->GetTaskParameters(task[source]); 00458 00459 for (int i=0; i < (int) params.size(); i++) 00460 { 00461 //std::string key = this->vars->GetVariable(params[i]); 00462 //if (this->vars->GetVariable(params[i]).compare("$") != 0) 00463 // params[i] = this->vars->GetVariable(params[i]); 00464 if ( this->inMap(this->task, params[i]) ) 00465 params[i] = this->unwrap( params[i] ); 00466 } 00467 } 00468 else // _A1 is NOT found in the map 00469 return "#"; 00470 } 00471 00472 // start the reassembly -- we've got it parsed now! 00473 unwrapped = fcn; // ex: unwrapped = diff 00474 unwrapped += "("; // ex: unwrapped = diff( 00475 00476 // loop through the params vector to unwrap each parameter 00477 00478 for(int i=0; i < (int) params.size(); i++) 00479 { 00480 //std::string temp = this->unwrap(params[i]); // unwrap the current param 00481 00482 //if (temp.size() == 0) // if temp is npos, there was an 00483 //unwrapped = "#"; // error, so preserve the error 00484 //else 00485 //{ // might need to update this once we have diff(_A1,_A2) to properly concat the params 00486 //unwrapped += temp; // otherwise, concat the results 00487 unwrapped += params[i];; 00488 00489 00490 if ( i < (int) params.size() - 1 ) // and if there are more to come 00491 unwrapped += ","; // add a comma 00492 } 00493 00494 00495 if (unwrapped.size() > 0 ) // if it's not errored 00496 unwrapped += ")"; // end the function 00497 00498 this->SetFullTaskName(source,unwrapped); 00499 return unwrapped; 00500 } 00501 00502 00503 /* 00504 function: parse 00505 purpose: parses command strings into functions and parameters 00506 00507 The evaluator list, eList, maps keys against functions (which take parameters 00508 of other keys) and base functions (which have parameters that don't contain keys). 00509 The first thing the evaluator needs to do to perform a function, given a command 00510 from the eList is to parse it, to know what it needs to know. 00511 00512 NOTE: DEPRECATED 00513 00514 input: 00515 source std:string containing the source command (ex: diff(_A1, _A2) 00516 fcn std::string* reference to the function string 00517 params std::vector<std::string>* reference to the parameter vector 00518 00519 output: 00520 fcn std::string* containing the function (ex: diff) 00521 params std::vector<std::string> containing the parameters of the function 00522 (ex: [ _A1, _A2 ] ) 00523 */ 00524 void EvaluatorList::parse(std::string source, std::string * fcn, std::vector<std::string> * params) 00525 { 00526 std::string temp = source; 00527 00528 // first, remove the trailing parenthesis 00529 // ex: 00530 // source: viewImage(_A1,MRI) 00531 // temp: viewImage(_A1,MRI 00532 temp = temp.substr(0,temp.find_last_of(")")); 00533 00534 //then, extract the function 00535 // ex: 00536 // temp: viewImage(_A1,MRI 00537 // fcn: viewImage 00538 *fcn = temp.substr(0,temp.find_first_of("(")); 00539 00540 // then, extract the variable list 00541 // ex: 00542 // temp: viewImage(_A1,MRI 00543 // temp: _A1,MRI 00544 temp = temp.substr(temp.find_first_of("(")+1); 00545 00546 // finally, create the vector of parameters 00547 // ex: 00548 // temp: _A1, MRI 00549 // params[0]: _A1 00550 // [1]: MRI 00551 std::string delim = ","; 00552 this->StringExplode(temp, delim, params); 00553 } 00554 00555 00556 /* 00557 function: StringExplode 00558 purpose: take a string and separate it based on some deliminator 00559 For instance: 00560 fruit = "apple, jackfruit, lemon, orange, pear, pineapple" 00561 separator = "," 00562 [ "apple" ] 00563 [ "jackfruit" ] 00564 results = [ "lemon" ] 00565 [ "orange" ] 00566 [ "pear" ] 00567 [ "pineapple" ] 00568 00569 input: 00570 str std::string string to be exploded 00571 separator std::string deliminator 00572 00573 output: 00574 results std::vector<std::string> vector of the separated string 00575 */ 00576 void EvaluatorList::StringExplode(std::string str, 00577 std::string separator, 00578 std::vector<std::string>* results) 00579 { 00580 size_t found = str.find_first_of(separator); 00581 while(found != std::string::npos){ 00582 if(found > 0){ 00583 // Strip spaces from left and right of string GEC 7/9/2010 00584 wxString temp(str.substr(0,found).c_str(), wxConvUTF8); 00585 temp.Trim(true); // Remove spaces from right of string 00586 temp.Trim(false); // Remove spaces from left of string 00587 results->push_back(std::string(temp.mb_str())); 00588 } 00589 str = str.substr(found+1); 00590 found = str.find_first_of(separator); 00591 } 00592 if(str.length() > 0){ 00593 // Strip spaces from left and right of string GEC 7/9/2010 00594 wxString temp(str.c_str(), wxConvUTF8 ); 00595 temp.Trim(true); // Remove spaces from right of string 00596 temp.Trim(false); // Remove spaces from left of string 00597 results->push_back(std::string(temp.mb_str())); 00598 } 00599 } 00600 00601 /* 00602 function: inMap 00603 purpose: To determine if a key is in a map 00604 00605 input: 00606 map std::map<S, T> map to be searched 00607 key S key to be searched 00608 00609 output: 00610 true: if found 00611 false: if not found 00612 */ 00613 template <typename S, typename T> 00614 bool EvaluatorList::inMap(std::map<S, T> map, S key) 00615 { 00616 bool flag = false; 00617 00618 typename std::map<S,T>::iterator keyfound = map.find(key); 00619 if (keyfound != map.end()){ 00620 flag = true; 00621 } 00622 00623 return flag; 00624 } 00625 00626 template bool EvaluatorList::inMap(std::map<std::string, std::string> map, std::string key);