00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
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
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
00184
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
00204
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
00225
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
00247
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
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
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
00322
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
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
00385
00386
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
00414
00415
00416
00417 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00418 d->showCursor(true) ;
00419
00420 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00421
00422 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00423
00424 SDL_Rect offset ;
00425 offset.x = (d->getWidth() - keypad->w) /2;
00426 offset.y = (d-> getHeight() - keypad->h) /2;
00427
00428 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00429
00430 string p = string("") ;
00431
00432 string tp = string("");
00433
00434 while( tp.compare("*")!=0 ){
00435
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
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
00463
00464
00465
00466
00467
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
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
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
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;
00743
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
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
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
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
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
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 ;
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
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
00888
00889
00890
00891
00892
00893
00894
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
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_2301.at(ind1);ind1++;break ;
00951 case 2 : testString = a_1032.at(ind2);ind2++;break ;
00952 case 3 : testString = d_2301.at(ind3);ind3++;break ;
00953 case 4 : testString = d_1032.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
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
01080 manager.stop();
01081
01082
01083
01084 return 0;
01085 }
01086
01087 #endif // INVT_HAVE_LIBSDL_IMAGE
01088