00001 /*!@file AppPsycho/psycho-3D-task-stimulus-classification.C psychopysics experiment for classifying the task and stimulus based on eye-movement data */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/App3DEye/psycho-3D-task-stimulus-classification.C $ 00035 // 00036 00037 #include "Component/ModelManager.H" 00038 #include "Image/Image.H" 00039 #include "Psycho/PsychoDisplay.H" 00040 #include "Psycho/EyeTrackerConfigurator.H" 00041 #include "Psycho/EyeTracker.H" 00042 #include "Psycho/PsychoOpts.H" 00043 #include "Component/EventLog.H" 00044 #include "Component/ComponentOpts.H" 00045 #include "Raster/Raster.H" 00046 #include "Util/MathFunctions.H" 00047 #include "Util/Types.H" 00048 #include "GameBoard/basic-graphics.H" 00049 #include <sys/types.h> 00050 #include <dirent.h> 00051 #include <errno.h> 00052 #include <vector> 00053 #include <string> 00054 #include <iostream> 00055 #include <SDL/SDL.h> 00056 #include <SDL/SDL_image.h> 00057 #include <SDL/SDL_mixer.h> 00058 #include <stdio.h> 00059 #include <stdlib.h> 00060 #include <sstream> 00061 #include <time.h> 00062 #include "Image/DrawOps.H" 00063 #include "GameBoard/resize.h" 00064 #include <iostream> 00065 #include <fstream> 00066 #include <set> 00067 #include <algorithm> 00068 #include <ctime> 00069 #include "Util/LEDcontroller.H" 00070 00071 #ifndef INVT_HAVE_LIBSDL_IMAGE 00072 #include <cstdio> 00073 int main() 00074 { 00075 fprintf(stderr, "The SDL_image library must be installed to use this program\n"); 00076 return 1; 00077 } 00078 00079 #else 00080 00081 00082 00083 using namespace std; 00084 00085 // ###################################################################### 00086 00087 ModelManager manager("Psycho 3D"); 00088 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager)); 00089 map<uint,uint> testMap ; 00090 map<string,string> argMap ; 00091 map<string,vector<SDL_Rect*>*> clipsmap; 00092 00093 ////////////////////////////////////////////// 00094 // a functionf for stringigying things 00095 ////////////////////////////////////////////// 00096 template <class T> std::string stringify(T i) 00097 { 00098 ostringstream o ; 00099 o << i ; 00100 return o.str(); 00101 } 00102 00103 00104 double getAvarage(vector<long> v){ 00105 double f = 0.0 ; 00106 for( uint i = 0 ; i < v.size() ; i++ ){ 00107 f += v[i] ; 00108 } 00109 if (v.size()!=0) return f/v.size() ; 00110 return -1 ; 00111 } 00112 00113 double getVariance(vector<long> v){ 00114 double m = getAvarage(v); 00115 double var = 0.0 ; 00116 for( uint i = 0 ; i < v.size(); i++ ){ 00117 var += (v[i]-m)*(v[i]-m) ; 00118 } 00119 if (v.size()!=0) return var/v.size() ; 00120 return -1 ; 00121 } 00122 00123 bool itIsInThere(int x , vector<int> bag){ 00124 for( uint i=0 ; i < bag.size(); i++ ){ 00125 if(x == bag[i]) return true ; 00126 } 00127 return false ; 00128 } 00129 00130 00131 string get34012(string s){ 00132 string t = ""; 00133 t = s.substr(3,1)+s.substr(4,1)+s.substr(0,1)+s.substr(1,1)+s.substr(2,1); 00134 return t ; 00135 } 00136 00137 string get21043(string s){ 00138 string t = ""; 00139 t = s.substr(2,1)+s.substr(1,1)+s.substr(0,1)+s.substr(4,1)+s.substr(3,1); 00140 return t ; 00141 } 00142 00143 string get41230(string s){ 00144 string t = ""; 00145 t = s.substr(4,1)+s.substr(1,1)+s.substr(2,1)+s.substr(3,1)+s.substr(0,1); 00146 return t ; 00147 } 00148 00149 string get03214(string s){ 00150 string t = ""; 00151 t = s.substr(0,1)+s.substr(3,1)+s.substr(2,1)+s.substr(1,1)+s.substr(4,1); 00152 return t ; 00153 } 00154 00155 string get42130(string s){ 00156 string t=""; 00157 t = s.substr(4,1)+s.substr(2,1)+s.substr(1,1)+s.substr(3,1)+s.substr(0,1); 00158 return t ; 00159 } 00160 00161 00162 string get03124(string s){ 00163 string t = "" ; 00164 t = s.substr(0,1)+s.substr(3,1)+s.substr(1,2)+s.substr(2,1)+s.substr(4,1); 00165 return t ; 00166 } 00167 00168 string get2301(string s){ 00169 string t = "" ; 00170 t = s.substr(2,1)+s.substr(3,1)+s.substr(0,1)+s.substr(1,1); 00171 return t; 00172 } 00173 00174 00175 string get1032(string s){ 00176 string t=""; 00177 t=s.substr(1,1)+s.substr(0,1)+s.substr(3,1)+s.substr(2,1); 00178 return t; 00179 } 00180 00181 00182 //////////////////////////////////////////////////////////////////// 00183 //// gets a string as the argument and returns a string composed of 00184 //// characters of the first string sorted in the ascending order 00185 /////////////////////////////////////////////////////////////////// 00186 string ascSort(string st) 00187 { 00188 string res = "" ; 00189 vector<string> v = vector<string>(); 00190 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ; 00191 00192 std::sort(v.begin(), v.end()); 00193 00194 for ( uint i = 0 ; i < v.size() ; i++ ){ 00195 res += v[i] ; 00196 } 00197 return res; 00198 } 00199 00200 00201 00202 //////////////////////////////////////////////////////////////////// 00203 //// gets a string as the argument and returns a string composed of 00204 //// characters of the first string sorted in the descending order 00205 /////////////////////////////////////////////////////////////////// 00206 string desSort(string st) 00207 { 00208 string res = "" ; 00209 vector<string> v = vector<string>(); 00210 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ; 00211 std::sort(v.begin(), v.end()); 00212 std::reverse(v.begin(), v.end()); 00213 for ( uint i = 0 ; i < v.size() ; i++ ){ 00214 res += v[i] ; 00215 } 00216 return res; 00217 } 00218 00219 00220 00221 00222 00223 //////////////////////////////////////////////////////// 00224 ///// simply generates a sequence of digits with given alphabet with length of l with given threshold, if the given threshold is not achieved the best answer with 00225 //highest metric value in 1000000 times try will be returned 00226 //////////////////////////////////////////////////////// 00227 00228 string getARandomString(uint l, string alphabet="0123456789"){ 00229 00230 string test = string("") ; 00231 test = "" ; 00232 string tp = string("") ; 00233 vector<int> pickedones = vector<int>() ; 00234 for(uint i = 0 ; i < l ; i++){ 00235 int nd; 00236 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ; 00237 pickedones.push_back(nd); 00238 tp = alphabet.substr(nd,1) ; 00239 test += tp ; 00240 } 00241 00242 return test ; 00243 } 00244 00245 /////////////////////////////////////////////////////// 00246 //this function is not called in this program, but it generates a random string and it will show it in 00247 //a random place on the screen. 00248 ////////////////////////////////////////////////////// 00249 string digitMemorizationTask(uint l, string alphabet="0123456789" , int displayFrame = 10 ){ 00250 d->clearScreen() ; 00251 vector<int> pickedones = vector<int>() ; 00252 string test = string("") ; 00253 string tp = string("") ; 00254 for(uint i = 0 ; i < l ; i++){ 00255 int nd; 00256 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ; 00257 pickedones.push_back(nd); 00258 tp = alphabet.substr(nd,1) ; 00259 test += tp ; 00260 } 00261 d->displayText(test,true,0) ; 00262 d->waitFrames(displayFrame) ; 00263 d->clearScreen() ; 00264 return test ; 00265 } 00266 00267 00268 //////////////////////////////////////////////////////// 00269 ///////this will change the order of elements in a vector to a random order 00270 //////////////////////////////////////////////////////// 00271 void scramble(vector<string>& v){ 00272 vector<string> tv = vector<string>() ; 00273 while(v.size()>0){ 00274 tv.push_back(v[0]); 00275 v.erase(v.begin()); 00276 } 00277 int i = 0 ; 00278 while(tv.size()>0){ 00279 i = rand()%tv.size() ; 00280 v.push_back(tv[i]); 00281 tv.erase(tv.begin()+i); 00282 } 00283 } 00284 00285 void scramble(vector<int>& v){ 00286 vector<int> tv = vector<int>() ; 00287 while(v.size()>0){ 00288 tv.push_back(v[0]); 00289 v.erase(v.begin()); 00290 } 00291 int i = 0 ; 00292 while(tv.size()>0){ 00293 i = rand()%tv.size() ; 00294 v.push_back(tv[i]); 00295 tv.erase(tv.begin()+i); 00296 } 00297 } 00298 00299 //////////////////////////////////////////////////////////////// 00300 ////This is our button factory 00301 //////////////////////////////////////////////////////////////// 00302 SDL_Surface* getButtonImage(string label , PixRGB<byte> txtcolor=PixRGB<byte>(0,0,0) , PixRGB<byte> bgcolor=PixRGB<byte>(255,255,255) ,Point2D<int> size = Point2D<int>(100,100) ,PixRGB<byte> bordercolor=PixRGB<byte>(0,0,0) , int border=3){ 00303 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS); 00304 textIm.clear(bgcolor); 00305 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor); 00306 SDL_Surface *surf = d->makeBlittableSurface(textIm , true); 00307 Uint32 bc = d->getUint32color(bordercolor); 00308 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border); 00309 SDL_Surface* blank =getABlankSurface(size.i , size.j); 00310 SDL_Rect clip; 00311 clip.x = 0 ; 00312 clip.y = 0 ; 00313 clip.w = size.i ; 00314 clip.h = size.j ; 00315 apply_surface(0,0,*surf,*blank,clip); 00316 dumpSurface(surf) ; 00317 return blank ; 00318 } 00319 00320 //////////////////////////////////////////////////////////////////////// 00321 ////This is the function for creating the keypad, in fact it generates 00322 ////12 buttons and associates the actions to the region for each button 00323 //////////////////////////////////////////////////////////////////////// 00324 00325 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){ 00326 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3); 00327 SDL_Rect clip; 00328 clip.x=0; 00329 clip.y=0; 00330 int numofrows = alphabet.size()/3 +1; 00331 if(alphabet.size()%3 != 0 ) numofrows++ ; 00332 int numofcolumns = 3 ; 00333 clip.w= pad->w / numofcolumns ; 00334 clip.h = pad->h / numofrows ; 00335 00336 //keys for 1 to 9 00337 for( int i = 0 ; i < numofrows*3 ; i++){ 00338 SDL_Surface* but ; 00339 if((uint)i < alphabet.size()){ 00340 but = getButtonImage(alphabet.substr(i,1),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3); 00341 }else{ 00342 but = getButtonImage(" ",PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3); 00343 } 00344 00345 SDL_Rect cl ; 00346 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ; 00347 cl.w = clip.w ; 00348 cl.h = clip.h ; 00349 apply_surface( cl.x , cl.y ,*but,*pad,clip); 00350 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ; 00351 dumpSurface(but); 00352 } 00353 SDL_Rect cl1 ; 00354 cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ; 00355 cl1.w = clip.w ; 00356 cl1.h = clip.h ; 00357 buttmap["!"] = cl1 ; 00358 SDL_Surface* but = getButtonImage(string("<-"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3); 00359 apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip); 00360 dumpSurface(but); 00361 SDL_Rect cl2 ; 00362 cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ; 00363 cl2.w = clip.w ; 00364 cl2.h = clip.h ; 00365 buttmap[" "] = cl2 ; 00366 but = getButtonImage(string("spc"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3); 00367 apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip); 00368 dumpSurface(but); 00369 SDL_Rect cl3 ; 00370 cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ; 00371 cl3.w = clip.w ; 00372 cl3.h = clip.h ; 00373 buttmap["*"] = cl3 ; 00374 but = getButtonImage(string("Ok"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / numofcolumns , pad->h / numofrows),PixRGB<byte>(255, 98 , 25),3); 00375 apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip); 00376 dumpSurface(but); 00377 return pad ; 00378 } 00379 00380 00381 00382 00383 /////////////////////////////////////////////////////////////////////////// 00384 /////this function listens to mouse clicks and then finds the region of the screen 00385 /////associated with the action, buttmap is the map of the region, offset is the offset of 00386 /////buttons 00387 /////////////////////////////////////////////////////////////////////////// 00388 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){ 00389 int quit = 0 ; 00390 string s ; 00391 SDL_Event event ; 00392 while( quit!=2 ){ 00393 while( SDL_PollEvent( &event ) ) { 00394 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){ 00395 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){ 00396 if(event.button.x >= (it->second).x + offset.i && event.button.x <= (it->second).x + (it->second).w + offset.i && event.button.y >= (it->second).y+ offset.j && event.button.y <= (it->second).y + (it->second).h + offset.j) { 00397 quit = 2 ; 00398 s = it->first ; 00399 break; 00400 } 00401 00402 } 00403 } 00404 00405 } 00406 } 00407 return s ; 00408 00409 } 00410 00411 00412 //////////////////////////////////////////////////// 00413 ////This function creates a virtual keypad, creates a map of buttons 00414 ////and their representation area and listens to the button press and at 00415 ////the end returns the keyed digits 00416 //////////////////////////////////////////////////// 00417 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){ 00418 d->showCursor(true) ; 00419 //let's creat a map to map actions to regions of the screen, each region is represented as an SDL_Rect 00420 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>(); 00421 //now let's get the keypad surface while we get the actions map to regions 00422 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap); 00423 //this will be the offset of displaying the keypad on the screen 00424 SDL_Rect offset ; 00425 offset.x = (d->getWidth() - keypad->w) /2; 00426 offset.y = (d-> getHeight() - keypad->h) /2; 00427 //now let's display the keypad 00428 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true); 00429 //this will hold the final string keyed be the subject 00430 string p = string("") ; 00431 //this is a temporary string holding the last action related to the pressed key 00432 string tp = string(""); 00433 //now let's record subject's key press 00434 while( tp.compare("*")!=0 ){ 00435 //this button is actually the display for the current string 00436 SDL_Surface* dp = getButtonImage(p ,PixRGB<byte>(195,60,12) ,PixRGB<byte>(255,255,255) ,Point2D<int>(d->getWidth()/6,d->getHeight() /15) ,PixRGB<byte>(0,25,180) , 4) ; 00437 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ; 00438 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ; 00439 //now let's listen to button events 00440 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ; 00441 dumpSurface(dp) ; 00442 if(tp.compare("!")==0 && p.size()>=0 ) { 00443 if (p.size()>0) p = p.substr(0,p.size()-1) ; 00444 }else{ 00445 if(p.size() < maxl && tp.compare("*")!=0) { 00446 p +=tp ; 00447 } 00448 00449 } 00450 00451 } 00452 buttmap = 0 ; 00453 dumpSurface(keypad) ; 00454 d->clearScreen() ; 00455 return p ; 00456 00457 } 00458 00459 00460 00461 /////////////////////////////////////////////////////////////// 00462 //////gets the test string, answer and the mode and identifies if 00463 //////the answer matches the thing it should be, mode=0 checks if 00464 //////if the answer and test string simply the same, mode=1 matches 00465 //////the answer against the ascending sorted string of the test string 00466 //////mode=2 compares the answer against the descending sorted of 00467 //////the test string 00468 /////////////////////////////////////////////////////////////// 00469 bool isAnswerCorrect(string test , string answer , int mode){ 00470 00471 if(mode == 0 && answer.compare(test)==0) return true ; 00472 00473 if(mode == 1 && answer.compare(ascSort(test))==0) return true ; 00474 00475 if(mode == 2 && answer.compare(desSort(test))==0) return true ; 00476 00477 return false; 00478 } 00479 00480 00481 00482 int addArgument(const string st,const string delim="="){ 00483 int i = st.find(delim) ; 00484 argMap[st.substr(0,i)] = st.substr(i+1); 00485 00486 return 0 ; 00487 } 00488 00489 std::string getArgumentValue(string arg){ 00490 return argMap[arg] ; 00491 } 00492 00493 std::string getUsageComment(){ 00494 00495 string com = string("\nlist of arguments : \n"); 00496 00497 com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ; 00498 com += "\nmemo=[a_string_without_white_space]\n"; 00499 com += "\nstring-size=[>0](the size of string){default=5} \n"; 00500 com += "\nsubject=[subject_name] \n" ; 00501 com += "\nnum-of-a-sorting-trials=[>1](number of ascending trials){default=2}\n"; 00502 com += "\nnum-of-d-sorting-trials=[>1](number of descending trials){default=2}\n"; 00503 com += "\nnum-of-mem-trials=[>1](number of trials){default=10}\n"; 00504 com += "\ndigit-onset=[>1] (number of frames that the string will remain onset ){default=10}\n"; 00505 com += "\nalphabet=[a string of characters](a string of characters){default=0123456789}\n"; 00506 com += "\nmode=[1,2,3,4](1 for displaying the whole number, 2 for random display , 3 for linear flashing disply , 4 for linear reverse flashing){default=1}\n"; 00507 com += "\ncue-wait-frames=[<0](number of frames to show the cue){default=0}\n"; 00508 com += "\nmask=[y/n](whether present a mask after presentation, n for no, y for yes ){default=n}\n" ; 00509 com += "\nmask-onset-frames=[<0](number of frames that mask will be onset){default=0}\n"; 00510 com += "\nwhite-space=[>0](the distance between digits in display){default=20}\n" ; 00511 com += "\ncue-type=[a/v](a for audio v for visual){default=v}\n"; 00512 com += "\nsound-dir=[path to wav files directory]{default=..}\n"; 00513 com += "\nfirst-stop=[a number](number of trials before the first recalibration){defalut=20}\n"; 00514 com += "\nsecond-stop=[a number](number of trials before the second recalibration){defalut=40}\n"; 00515 com += "\nthird-stop=[a number](number of trials before the third recalibration){defalut=60}\n"; 00516 com += "\nasc-cue-sound-file=[file name for ascending cue operation]{defualt=sine.wav}\n"; 00517 com += "\ndesc-cue-sound-file=[file name for ascending cue operation]{defualt=square.wav}\n"; 00518 return com ; 00519 } 00520 00521 00522 void displayWholeNumber(string s , int onsetTime , int wsd){ 00523 int x = (d->getWidth()-s.size()*wsd)/2 ; 00524 int y = (d->getHeight())/2 -10; 00525 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS); 00526 textIm.clear(PixRGB<byte>(128,128,128)); 00527 for( uint k = 0 ; k < s.size() ; k++ ){ 00528 // d->displayText(s.substr(k,1),Point2D<int>(x,y+k*10),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ; 00529 writeText(textIm, Point2D<int>(x+k*wsd,y),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128)); 00530 } 00531 SDL_Surface *surf = d->makeBlittableSurface(textIm , true); 00532 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ; 00533 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ; 00534 dumpSurface(surf); 00535 d->waitFrames(onsetTime); 00536 d->clearScreen() ; 00537 } 00538 00539 void displayWholeNumberVertically(string s , int onsetTime , int wsd){ 00540 int x = (d->getWidth())/2 ; 00541 int y = (d->getHeight()-s.size()*wsd)/2 ; 00542 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS); 00543 textIm.clear(PixRGB<byte>(128,128,128)); 00544 for( uint k = 0 ; k < s.size() ; k++ ){ 00545 // d->displayText(s.substr(k,1),Point2D<int>(x,y+k*10),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ; 00546 writeText(textIm, Point2D<int>(x,y+k*wsd),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128)); 00547 } 00548 SDL_Surface *surf = d->makeBlittableSurface(textIm , true); 00549 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ; 00550 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ; 00551 dumpSurface(surf); 00552 d->waitFrames(onsetTime); 00553 d->clearScreen() ; 00554 } 00555 00556 void displayRandom(string s , int onsetTime){ 00557 for( uint k = 0 ; k < s.size() ; k++ ){ 00558 int x = 9*d->getWidth()/20 + rand()%(d->getWidth()/10); 00559 int y = 9*d->getHeight()/20 + rand()%(d->getHeight()/10) ; 00560 d->displayText(s.substr(k,1),Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ; 00561 d->waitFrames(onsetTime); 00562 d->clearScreen() ; 00563 } 00564 } 00565 00566 void displayLinear(string s , int onsetTime, int ws ){ 00567 int x = (d->getWidth()-(s.size()-1)*ws)/2 ; 00568 int y = d->getHeight()/2 - 10; 00569 for( uint k = 0 ; k < s.size() ; k++ ){ 00570 d->displayText(s.substr(k,1),Point2D<int>(x+k*ws,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ; 00571 d->waitFrames(onsetTime); 00572 d->clearScreen() ; 00573 } 00574 } 00575 00576 void displayLinearReverse(string s , int onsetTime){ 00577 int x = (d->getWidth()-s.size()*10)/2 ; 00578 int y = d->getHeight()/2 - 10; 00579 for( uint k = 0 ; k < s.size() ; k++ ){ 00580 d->displayText(s.substr(k,1),Point2D<int>(x+(s.size()-k)*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ; 00581 d->waitFrames(onsetTime); 00582 d->clearScreen() ; 00583 } 00584 } 00585 void displayLinearRandom(string s , int onsetTime){ 00586 int x = (d->getWidth()-s.size()*10)/2 ; 00587 int y = d->getHeight()/2 - 10; 00588 for( uint k = 0 ; k < s.size() ; k++ ){ 00589 d->displayText(s.substr(k,1),Point2D<int>(x+ (random()%s.size())*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ; 00590 d->waitFrames(onsetTime); 00591 d->clearScreen() ; 00592 } 00593 } 00594 00595 void displayLinearRandomVertically(string s , int onsetTime){ 00596 int x = (d->getWidth())/2 ; 00597 int y = (d->getHeight()-s.size()*10)/2 - 10; 00598 for( uint k = 0 ; k < s.size() ; k++ ){ 00599 d->displayText(s.substr(k,1),Point2D<int>(x, (random()%s.size())*10+y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ; 00600 d->waitFrames(onsetTime); 00601 d->clearScreen() ; 00602 } 00603 } 00604 00605 void displayLinearRandomNoRepeating(string s , int onsetTime){ 00606 int x = (d->getWidth()-s.size()*10)/2 ; 00607 int y = d->getHeight()/2 - 10; 00608 for( uint k = 0 ; k < s.size() ; k++ ){ 00609 d->displayText(s.substr(k,1),Point2D<int>(x+ (random()%s.size())*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ; 00610 d->waitFrames(onsetTime); 00611 d->clearScreen() ; 00612 } 00613 } 00614 00615 //and this is the function which creates and displays a mask of randomly positioned numbers 00616 void showMask(int frames, string alphabet="0123456789"){ 00617 d->clearScreen(); 00618 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS); 00619 PixRGB<byte> bgcolor = PixRGB<byte>(128,128,128); 00620 PixRGB<byte> txtcolor = PixRGB<byte>(0,0,0); 00621 textIm.clear(bgcolor); 00622 for(int i = 0 ; i < 800 ; i++) 00623 writeText(textIm, Point2D<int>((int)random()%(d->getWidth()),(int)random()%(d->getHeight())),alphabet.substr(random()%(int)alphabet.size(),1).c_str(),txtcolor,bgcolor); 00624 SDL_Surface *surf = d->makeBlittableSurface(textIm , true); 00625 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ; 00626 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ; 00627 d->waitFrames(frames) ; 00628 d->clearScreen(); 00629 dumpSurface(surf) ; 00630 } 00631 00632 00633 vector<string> getAll_34012(string al="0123456789"){ 00634 string tmp; 00635 vector<string> outVector ; 00636 for(int i0=0 ;i0<10 ;i0++ ){ 00637 for( int i1=i0+2;i1<10 ; i1++ ){ 00638 for( int i2=i1+2 ;i2<10 ; i2++){ 00639 for( int i3=i2+1 ; i3 <10 ; i3++ ){ 00640 for( int i4=i3+2; i4 < 10 ; i4++){ 00641 tmp = al.substr(i3,1)+al.substr(i4,1)+al.substr(i0,1)+al.substr(i1,1)+al.substr(i2,1); 00642 outVector.push_back(tmp); 00643 } 00644 } 00645 } 00646 } 00647 } 00648 return outVector ; 00649 } 00650 00651 vector<string> getAll_21043(string al="0123456789"){ 00652 string tmp; 00653 vector<string> outVector ; 00654 for(int i0=0 ;i0<10 ;i0++ ){ 00655 for( int i1=i0+2;i1<10 ; i1++ ){ 00656 for( int i2=i1+2 ;i2<10 ; i2++){ 00657 for( int i3=i2+1 ; i3 <10 ; i3++ ){ 00658 for( int i4=i3+2; i4 < 10 ; i4++){ 00659 tmp = al.substr(i2,1)+al.substr(i1,1)+al.substr(i0,1)+al.substr(i4,1)+al.substr(i3,1); 00660 outVector.push_back(tmp); 00661 } 00662 } 00663 } 00664 } 00665 } 00666 return outVector ; 00667 } 00668 vector<string> getAll_41230(string al="0123456789"){ 00669 string tmp; 00670 vector<string> outVector ; 00671 for(uint i0=0 ;i0<al.size() ;i0++ ){ 00672 for( uint i1=i0+1;i1<al.size() ; i1++ ){ 00673 for( uint i2=i1+2 ;i2<al.size() ; i2++){ 00674 for( uint i3=i2+2 ; i3 <al.size() ; i3++ ){ 00675 for( uint i4=i3+1; i4 < al.size() ; i4++){ 00676 tmp = al.substr(i4,1)+al.substr(i1,1)+al.substr(i2,1)+al.substr(i3,1)+al.substr(i0,1); 00677 outVector.push_back(tmp); 00678 } 00679 } 00680 } 00681 } 00682 } 00683 return outVector ; 00684 } 00685 00686 vector<string> getAll_03214(string al="0123456789"){ 00687 string tmp; 00688 vector<string> outVector ; 00689 for(uint i0=0 ;i0<al.size() ;i0++ ){ 00690 for( uint i1=i0+1;i1<al.size() ; i1++ ){ 00691 for( uint i2=i1+2 ;i2<al.size() ; i2++){ 00692 for( uint i3=i2+2 ; i3 <al.size() ; i3++ ){ 00693 for( uint i4=i3+1; i4 < al.size() ; i4++){ 00694 tmp = al.substr(i0,1)+al.substr(i3,1)+al.substr(i2,1)+al.substr(i1,1)+al.substr(i4,1); 00695 outVector.push_back(tmp); 00696 } 00697 } 00698 } 00699 } 00700 } 00701 return outVector ; 00702 } 00703 00704 vector<string> getAll_2301(string al="0123456789"){ 00705 string tmp; 00706 vector<string> outVector; 00707 for(uint i0=0 ;i0<al.size() ;i0++ ){ 00708 for( uint i1=i0+1;i1<al.size() ; i1++ ){ 00709 for( uint i2=i1+2 ;i2<al.size() ; i2++){ 00710 for( uint i3=i2+2 ; i3 <al.size() ; i3++ ){ 00711 tmp = al.substr(i2,1)+al.substr(i3,1)+al.substr(i0,1)+al.substr(i1,1); 00712 outVector.push_back(tmp); 00713 } 00714 } 00715 } 00716 } 00717 00718 return outVector; 00719 } 00720 00721 vector<string> getAll_1032(string al="0123456789"){ 00722 string tmp; 00723 vector<string> outVector; 00724 for(uint i0=0 ;i0<al.size() ;i0++ ){ 00725 for( uint i1=i0+1;i1<al.size() ; i1++ ){ 00726 for( uint i2=i1+2 ;i2<al.size() ; i2++){ 00727 for( uint i3=i2+2 ; i3 <al.size() ; i3++ ){ 00728 tmp = al.substr(i1,1)+al.substr(i0,1)+al.substr(i3,1)+al.substr(i2,1); 00729 outVector.push_back(tmp); 00730 } 00731 } 00732 } 00733 } 00734 00735 return outVector; 00736 } 00737 00738 00739 extern "C" int main(const int argc, char** argv) 00740 { 00741 00742 MYLOGVERB = LOG_INFO; // suppress debug messages 00743 //let's push the initial value for the parameters 00744 argMap["experiment"]="working memory single task - sorting"; 00745 argMap["logfile"]="psycho-sorting-const.psy" ; 00746 argMap["string-size"]="5" ; 00747 argMap["subject"]="" ; 00748 argMap["memo"]="" ; 00749 argMap["digit-onset"]="10" ; 00750 argMap["alphabet"]="0123456789"; 00751 argMap["mode"]="1" ; 00752 argMap["cue-wait-frames"]="0" ; 00753 argMap["mask"]="n" ; 00754 argMap["cue-onset-frames"] = "3" ; 00755 argMap["white-space"] = "30" ; 00756 argMap["cue-type"] = "v" ; 00757 argMap["sound-dir"]=".."; 00758 argMap["num-of-a-sorting-trials"] = "2" ; 00759 argMap["num-of-d-sorting-trials"] = "2" ; 00760 argMap["num-of-mem-trials"] = "2" ; 00761 argMap["first-stop"]="20"; 00762 argMap["second-stop"]="40"; 00763 argMap["third-stop"] = "60"; 00764 argMap["asc-cue-sound-file"]="sine.wav"; 00765 argMap["desc-cue-sound-file"]="square.wav"; 00766 manager.addSubComponent(d); 00767 nub::soft_ref<EventLog> el(new EventLog(manager)); 00768 manager.addSubComponent(el); 00769 nub::soft_ref<LEDcontroller> itsledcon(new LEDcontroller(manager)); 00770 manager.addSubComponent(itsledcon); 00771 00772 d->setEventLog(el); 00773 nub::soft_ref<EyeTrackerConfigurator> 00774 etc(new EyeTrackerConfigurator(manager)); 00775 manager.addSubComponent(etc); 00776 00777 if (manager.parseCommandLine(argc, argv, 00778 "at least one argument needed", 1, -1)==false){ 00779 cout<<getUsageComment()<<endl; 00780 return(1); 00781 } 00782 00783 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){ 00784 addArgument(manager.getExtraArg(i),std::string("=")) ; 00785 } 00786 00787 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]); 00788 manager.setOptionValString(&OPT_EyeTrackerType, "EL"); 00789 nub::soft_ref<EyeTracker> eyet = etc->getET(); 00790 d->setEyeTracker(eyet); 00791 eyet->setEventLog(el); 00792 00793 00794 // let's get all our ModelComponent instances started: 00795 manager.start(); 00796 eyet->setBackgroundColor(d); 00797 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ; 00798 // let's display an ISCAN calibration grid: 00799 d->clearScreen(); 00800 d->displayISCANcalib(); 00801 d->waitForMouseClick(); 00802 d->displayText("Here the experiment starts! click to start!"); 00803 d->waitForMouseClick(); 00804 d->clearScreen(); 00805 //let's see in what mode the user like to run the program 00806 int mode = atoi(argMap["mode"].c_str()); 00807 vector<long> correctAnswersTiming; 00808 vector<long> incorrectAnswersTiming; 00809 vector<long> allTiming ; 00810 int correctMemory = 0 ; 00811 int incorrectMemory = 0 ; 00812 int correctAsc = 0 ; 00813 int incorrectAsc = 0 ; 00814 int correctDes = 0 ; 00815 int incorrectDes = 0 ; 00816 int stringSize = atoi(argMap["string-size"].c_str()); 00817 int onsetDel = atoi(argMap["digit-onset"].c_str()) ; 00818 int cue_wait_frames = atoi(argMap["cue-wait-frames"].c_str()) ; 00819 int mask_onset_frames = atoi(argMap["mask-onset-frames"].c_str()) ; 00820 int white_sapece_distance = atoi(argMap["white-space"].c_str()); 00821 int num_of_a_sorting_task = atoi(argMap["num-of-a-sorting-trials"].c_str()) ; 00822 int num_of_d_sorting_task = atoi(argMap["num-of-d-sorting-trials"].c_str()) ; 00823 int num_of_mem_task = atoi(argMap["num-of-mem-trials"].c_str()) ; 00824 int first_stop = atoi(argMap["first-stop"].c_str()); 00825 int second_stop = atoi(argMap["second-stop"].c_str()); 00826 int third_stop = atoi(argMap["third-stop"].c_str()); 00827 string alphabet = argMap["alphabet"]; 00828 //let's do calibration 00829 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip"); 00830 int cl = d->waitForMouseClick(); 00831 if (cl == 1) eyet->calibrate(d); 00832 d->clearScreen() ; 00833 d->displayText("CLICK LEFT button for off-screen clibration; RIGHT to skip"); 00834 cl = d->waitForMouseClick(); 00835 //now time for offscreen calibration 00836 if (cl==1){ 00837 for(int i=1;i<5;i++){ 00838 d->clearScreen(); 00839 string s = stringify(i); 00840 d->displayText(s); 00841 itsledcon -> setLED(i,true); 00842 usleep(1250000); 00843 d->pushEvent("displayEvent start LEDCALIB" +s); 00844 eyet->track(true); 00845 d->waitFrames(60); 00846 d->pushEvent("displayEvent stop LEDCALIB" +s); 00847 eyet->track(false); 00848 itsledcon -> setLED(i,false); 00849 d->waitForMouseClick(); 00850 } 00851 } 00852 map<int,Mix_Music*> audio_map ;//we will have access to the audios for stimulus presentation using this map 00853 map<string,int> charmap ; 00854 map<int,string> charinvmap ; 00855 Mix_Music* recallCueMusic = NULL; 00856 Mix_Music* sortCueMusic = NULL; 00857 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){ 00858 LINFO( "did not open the mix-audio") ; 00859 return -1 ; 00860 } 00861 string str = argMap["sound-dir"]+"/"+argMap["asc-cue-sound-file"] ; 00862 recallCueMusic = Mix_LoadMUS(str.c_str()); 00863 if(recallCueMusic==NULL) cout<<"not a 16 bit wav file "<<str<<endl; 00864 str = argMap["sound-dir"]+"/"+argMap["desc-cue-sound-file"] ; 00865 sortCueMusic = Mix_LoadMUS(str.c_str()); 00866 if(sortCueMusic==NULL) cout<<"not a 16 bit wav file "<<str<<endl; 00867 if(argMap["cue-type"].compare("a")==0){ 00868 //now let's open the audio channel 00869 for(uint i = 0; i < alphabet.size() ; i++){ 00870 string str = argMap["sound-dir"]+"/"+alphabet.substr(i,1)+".wav"; 00871 audio_map[i]=Mix_LoadMUS(str.c_str()); 00872 if(audio_map[i]==NULL) cout<<"not a 16 bit wav file "<<str<<endl; 00873 charmap[alphabet.substr(i,1)]=i; 00874 charinvmap[i]=alphabet.substr(i,1) ; 00875 } 00876 } 00877 vector<int>* taskVector = new vector<int>(); 00878 for(int i = 0 ; i < (int)(num_of_a_sorting_task/2) ; i++) { 00879 taskVector->push_back(1); 00880 taskVector->push_back(2); 00881 } 00882 for(int i = 0 ; i < (int)(num_of_d_sorting_task/2) ; i++) { 00883 taskVector->push_back(3); 00884 taskVector->push_back(4); 00885 } 00886 00887 vector<string> a_41230 = getAll_41230(alphabet); 00888 vector<string> a_03214 = getAll_03214(alphabet); 00889 vector<string> d_41230 = getAll_41230(alphabet); 00890 vector<string> d_03214 = getAll_03214(alphabet); 00891 scramble(a_41230); 00892 scramble(a_03214); 00893 scramble(d_41230); 00894 scramble(d_03214); 00895 00896 /* 00897 vector<string> a_2301 = getAll_2301(alphabet); 00898 vector<string> a_1032 = getAll_1032(alphabet); 00899 vector<string> d_2301 = getAll_2301(alphabet); 00900 vector<string> d_1032 = getAll_1032(alphabet); 00901 scramble(a_2301); 00902 scramble(a_1032); 00903 scramble(d_2301); 00904 scramble(d_1032); 00905 */ 00906 string imst ; 00907 int ind1 = 0 ; int ind2 = 0 ; int ind3 = 0 ;int ind4 = 0 ; 00908 for(int i = 0 ; i < num_of_mem_task ; i++) taskVector->push_back(0); 00909 scramble(*taskVector); 00910 for( int r = 0 ; (int)r < (int)taskVector->size() ; r++ ){ 00911 00912 if(r==first_stop || r==second_stop || r==third_stop){ 00913 d->displayText("YOU MAY STOP HERE TO TAKE A SHORT BRAKE!"); 00914 d->waitForMouseClick(); 00915 d->displayText("incorrect memory recalls="+stringify(incorrectMemory)+" incorrect ascending sorting:"+stringify(incorrectAsc) + " incorrect descencing sorting"+ stringify(incorrectDes) ); 00916 d->waitForMouseClick(); 00917 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip"); 00918 int cl = d->waitForMouseClick(); 00919 if (cl == 1) eyet->calibrate(d);; 00920 d->clearScreen() ; 00921 d->displayText("CLICK LEFT button for off-screen clibration; RIGHT to skip"); 00922 cl = d->waitForMouseClick(); 00923 //refreshing offscreen calibration 00924 if (cl==1){ 00925 for(int i=1;i<5;i++){ 00926 d->clearScreen(); 00927 string s = stringify(i); 00928 d->displayText(s); 00929 itsledcon -> setLED(i,true); 00930 usleep(1500000); 00931 d->pushEvent("displayEvent start LEDCALIB" +s); 00932 eyet->track(true); 00933 d->waitFrames(60); 00934 d->pushEvent("displayEvent stop LEDCALIB" +s); 00935 eyet->track(false); 00936 itsledcon -> setLED(i,false); 00937 d->waitForMouseClick(); 00938 } 00939 } 00940 } 00941 00942 int task = taskVector->at(r) ; 00943 d->pushEvent("**************************************") ; 00944 d->showCursor(false); 00945 d->displayText("click one of the mouse buttons to start!"); 00946 d->waitForMouseClick() ; 00947 string testString ; 00948 testString = getARandomString(stringSize,alphabet); 00949 switch( task ){ 00950 case 1 : testString = a_41230.at(ind1);ind1++;break ; 00951 case 2 : testString = a_03214.at(ind2);ind2++;break ; 00952 case 3 : testString = d_41230.at(ind3);ind3++;break ; 00953 case 4 : testString = d_03214.at(ind4);ind4++;break ; 00954 } 00955 cout<<r<<"-"<<task<<endl; 00956 d->clearScreen() ; 00957 d->displayFixationBlink(); 00958 if(mode==0){ 00959 imst= "audioEvent start STIMULUS PLAYING "+stringify(task)+"_"+stringify(r)+"_"+testString; 00960 d->pushEvent(imst); 00961 for(int i = 0 ; i < (int)testString.size(); i++){ 00962 if( Mix_PlayMusic( audio_map[charmap[testString.substr(i,1)]], 0 ) == -1 ) { return 1; } 00963 while( Mix_PlayingMusic() == 1 ){} 00964 d->waitFrames(onsetDel); 00965 } 00966 imst= "audioEvent stop STIMULUS PLAYING "+stringify(task)+"_"+stringify(r)+"_"+testString; 00967 d->pushEvent(imst); 00968 }else{ 00969 if(task== 0){ 00970 imst= "displayEvent start DUMMY ONSET "+stringify(task)+"_"+stringify(r)+"_"+testString; 00971 }else{ 00972 imst= "displayEvent start STIMULUS ONSET "+stringify(task)+"_"+stringify(r)+"_"+testString; 00973 } 00974 00975 d->pushEvent(imst); 00976 switch( mode ){ 00977 case 1 : displayWholeNumber(testString,onsetDel,white_sapece_distance);break ; 00978 case 2 : displayRandom(testString,onsetDel) ; break ; 00979 case 3 : displayLinear(testString,onsetDel,white_sapece_distance) ; break ; 00980 case 4 : displayLinearRandom(testString,onsetDel) ; break ; 00981 case 5 : displayLinearReverse(testString,onsetDel) ; break ; 00982 case 6 : displayLinearRandomVertically(testString,onsetDel) ; break ; 00983 case 7 : displayWholeNumberVertically(testString,onsetDel,white_sapece_distance) ; break ; 00984 } 00985 if(task== 0){ 00986 imst= "displayEvent stop DUMMY ONSET "+stringify(task)+"_"+stringify(r)+"_"+testString; 00987 }else{ 00988 imst= "displayEvent stop STIMULUS ONSET "+stringify(task)+"_"+stringify(r)+"_"+testString; 00989 } 00990 00991 d->pushEvent(imst); 00992 00993 } 00994 d->displayFixation() ; 00995 00996 if(argMap["mask"].compare("y")==0) showMask(mask_onset_frames,argMap["alphabet"]); 00997 if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ; 00998 d->displayFixation() ; 00999 01000 01001 if(task == 0 ) {d->displayRedDotFixation();d->waitFrames(10);} 01002 if(task == 1 || task ==2 ){if( Mix_PlayMusic( recallCueMusic, 0 ) == -1 ) { return 1; } 01003 while( Mix_PlayingMusic() == 1 ){} 01004 } 01005 if(task==3 || task==4){ 01006 if( Mix_PlayMusic( sortCueMusic, 0 ) == -1 ) { return 1; } 01007 while( Mix_PlayingMusic() == 1 ){} 01008 } 01009 01010 01011 //d->clearScreen() ; 01012 01013 if(task!=0){ 01014 01015 d->pushEvent("the sequence for operation is : "+testString) ; 01016 imst= "ETEvent start"; 01017 d->pushEvent(imst); 01018 eyet->track(true); 01019 d->waitForMouseClick(); 01020 eyet->track(false); 01021 imst= "ETEvent stop"; 01022 d->pushEvent(imst); 01023 d->pushEvent("task ends") ; 01024 string answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size()); 01025 d->pushEvent("subject keyed : "+answer); 01026 if((task==1 || task==2) && answer.compare(ascSort(testString))==0){ 01027 d->pushEvent("answer was correct"); 01028 correctAsc++ ; 01029 d->displayText(":)"); 01030 d->waitFrames(20); 01031 } 01032 if((task==1 || task==2) && answer.compare(ascSort(testString))!=0){ 01033 d->pushEvent("answer was incorrect"); 01034 incorrectAsc++ ; 01035 d->displayText(":("); 01036 d->waitFrames(20); 01037 } 01038 01039 if((task==3 || task==4) && answer.compare(desSort(testString))==0){ 01040 d->pushEvent("answer was correct"); 01041 correctDes++; 01042 d->displayText(":)"); 01043 d->waitFrames(20); 01044 } 01045 if((task==3 || task==4) && answer.compare(desSort(testString))!=0){ 01046 d->pushEvent("answer was incorrect"); 01047 incorrectDes++; 01048 d->displayText(":("); 01049 d->waitFrames(20); 01050 } 01051 01052 }else{ 01053 string answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size()); 01054 d->pushEvent("subject keyed : "+answer); 01055 if(answer.compare(testString)==0){ 01056 d->pushEvent("recall was correct"); 01057 correctMemory++ ; 01058 d->displayText(":)"); 01059 d->waitFrames(20); 01060 }else{ 01061 d->pushEvent("recall was incorrect"); 01062 incorrectMemory++ ; 01063 d->displayText(":("); 01064 d->waitFrames(20); 01065 } 01066 } 01067 01068 } 01069 d->pushEvent("number of correct memory recall : "+ stringify(correctMemory)) ; 01070 d->pushEvent("number of incorrect memory recall : "+ stringify(incorrectMemory)) ; 01071 d->pushEvent("number of correct ascending sorting :"+stringify(correctAsc)); 01072 d->pushEvent("number of incorrect ascending sorting :"+stringify(incorrectAsc)); 01073 d->pushEvent("number of correct descending sorting :"+stringify(correctDes)); 01074 d->pushEvent("number of incorrect descending sorting :"+stringify(incorrectDes)); 01075 d->clearScreen(); 01076 d->displayText("Experiment complete. Thank you!"); 01077 d->waitForMouseClick(); 01078 taskVector = 0 ; 01079 // stop all our ModelComponents 01080 manager.stop(); 01081 01082 01083 // all done! 01084 return 0; 01085 } 01086 01087 #endif // INVT_HAVE_LIBSDL_IMAGE 01088