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
00038 #include "Component/ModelManager.H"
00039 #include "Image/Image.H"
00040 #include "Psycho/PsychoDisplay.H"
00041 #include "Psycho/EyeTrackerConfigurator.H"
00042 #include "Psycho/EyeTracker.H"
00043 #include "Psycho/PsychoOpts.H"
00044 #include "Component/EventLog.H"
00045 #include "Component/ComponentOpts.H"
00046 #include "Raster/Raster.H"
00047 #include "Util/MathFunctions.H"
00048 #include "Util/Types.H"
00049 #include "GameBoard/basic-graphics.H"
00050 #include <sys/types.h>
00051 #include <dirent.h>
00052 #include <errno.h>
00053 #include <vector>
00054 #include <string>
00055 #include <iostream>
00056 #include <SDL/SDL.h>
00057 #include <SDL/SDL_image.h>
00058 #include <SDL/SDL_mixer.h>
00059 #include <stdio.h>
00060 #include <stdlib.h>
00061 #include <sstream>
00062 #include <time.h>
00063 #include "Image/DrawOps.H"
00064 #include "GameBoard/resize.h"
00065 #include <iostream>
00066 #include <fstream>
00067 #include <set>
00068 #include <algorithm>
00069 #include <ctime>
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-Concurrent-Digit");
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
00169
00170
00171 string ascSort(string st)
00172 {
00173 string res = "" ;
00174 vector<string> v = vector<string>();
00175 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00176
00177 std::sort(v.begin(), v.end());
00178
00179 for ( uint i = 0 ; i < v.size() ; i++ ){
00180 res += v[i] ;
00181 }
00182 return res;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191 string desSort(string st)
00192 {
00193 string res = "" ;
00194 vector<string> v = vector<string>();
00195 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00196 std::sort(v.begin(), v.end());
00197 std::reverse(v.begin(), v.end());
00198 for ( uint i = 0 ; i < v.size() ; i++ ){
00199 res += v[i] ;
00200 }
00201 return res;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 string getARandomString(uint l, string alphabet="0123456789"){
00214
00215 string test = string("") ;
00216 test = "" ;
00217 string tp = string("") ;
00218 vector<int> pickedones = vector<int>() ;
00219 for(uint i = 0 ; i < l ; i++){
00220 int nd;
00221 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00222 pickedones.push_back(nd);
00223 tp = alphabet.substr(nd,1) ;
00224 test += tp ;
00225 }
00226
00227 return test ;
00228 }
00229
00230
00231
00232
00233
00234 string digitMemorizationTask(uint l, string alphabet="0123456789" , int displayFrame = 10 ){
00235 d->clearScreen() ;
00236 vector<int> pickedones = vector<int>() ;
00237 string test = string("") ;
00238 string tp = string("") ;
00239 for(uint i = 0 ; i < l ; i++){
00240 int nd;
00241 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00242 pickedones.push_back(nd);
00243 tp = alphabet.substr(nd,1) ;
00244 test += tp ;
00245 }
00246 d->displayText(test,true,0) ;
00247 d->waitFrames(displayFrame) ;
00248 d->clearScreen() ;
00249 return test ;
00250 }
00251
00252
00253
00254
00255
00256 void scramble(vector<string>& v){
00257 vector<string> tv = vector<string>() ;
00258 while(v.size()>0){
00259 tv.push_back(v[0]);
00260 v.erase(v.begin());
00261 }
00262 int i = 0 ;
00263 while(tv.size()>0){
00264 i = rand()%tv.size() ;
00265 v.push_back(tv[i]);
00266 tv.erase(tv.begin()+i);
00267 }
00268 }
00269
00270 void scramble(vector<int>& v){
00271 vector<int> tv = vector<int>() ;
00272 while(v.size()>0){
00273 tv.push_back(v[0]);
00274 v.erase(v.begin());
00275 }
00276 int i = 0 ;
00277 while(tv.size()>0){
00278 i = rand()%tv.size() ;
00279 v.push_back(tv[i]);
00280 tv.erase(tv.begin()+i);
00281 }
00282 }
00283
00284
00285
00286
00287 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){
00288 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00289 textIm.clear(bgcolor);
00290 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00291 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00292 Uint32 bc = d->getUint32color(bordercolor);
00293 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00294 SDL_Surface* blank =getABlankSurface(size.i , size.j);
00295 SDL_Rect clip;
00296 clip.x = 0 ;
00297 clip.y = 0 ;
00298 clip.w = size.i ;
00299 clip.h = size.j ;
00300 apply_surface(0,0,*surf,*blank,clip);
00301 dumpSurface(surf) ;
00302 return blank ;
00303 }
00304
00305
00306
00307
00308
00309
00310 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00311 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00312 SDL_Rect clip;
00313 clip.x=0;
00314 clip.y=0;
00315 int numofrows = alphabet.size()/3 +1;
00316 if(alphabet.size()%3 != 0 ) numofrows++ ;
00317 int numofcolumns = 3 ;
00318 clip.w= pad->w / numofcolumns ;
00319 clip.h = pad->h / numofrows ;
00320
00321
00322 for( int i = 0 ; i < numofrows*3 ; i++){
00323 SDL_Surface* but ;
00324 if((uint)i < alphabet.size()){
00325 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);
00326 }else{
00327 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);
00328 }
00329
00330 SDL_Rect cl ;
00331 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00332 cl.w = clip.w ;
00333 cl.h = clip.h ;
00334 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00335 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00336 dumpSurface(but);
00337 }
00338 SDL_Rect cl1 ;
00339 cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00340 cl1.w = clip.w ;
00341 cl1.h = clip.h ;
00342 buttmap["!"] = cl1 ;
00343 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);
00344 apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00345 dumpSurface(but);
00346 SDL_Rect cl2 ;
00347 cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00348 cl2.w = clip.w ;
00349 cl2.h = clip.h ;
00350 buttmap[" "] = cl2 ;
00351 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);
00352 apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00353 dumpSurface(but);
00354 SDL_Rect cl3 ;
00355 cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00356 cl3.w = clip.w ;
00357 cl3.h = clip.h ;
00358 buttmap["*"] = cl3 ;
00359 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);
00360 apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00361 dumpSurface(but);
00362 return pad ;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00374 int quit = 0 ;
00375 string s ;
00376 SDL_Event event ;
00377 while( quit!=2 ){
00378 while( SDL_PollEvent( &event ) ) {
00379 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){
00380 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00381 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) {
00382 quit = 2 ;
00383 s = it->first ;
00384 break;
00385 }
00386
00387 }
00388 }
00389
00390 }
00391 }
00392 return s ;
00393
00394 }
00395
00396
00397
00398
00399
00400
00401
00402 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00403 d->showCursor(true) ;
00404
00405 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00406
00407 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00408
00409 SDL_Rect offset ;
00410 offset.x = (d->getWidth() - keypad->w) /2;
00411 offset.y = (d-> getHeight() - keypad->h) /2;
00412
00413 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00414
00415 string p = string("") ;
00416
00417 string tp = string("");
00418
00419 while( tp.compare("*")!=0 ){
00420
00421 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) ;
00422 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00423 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00424
00425 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00426 dumpSurface(dp) ;
00427 if(tp.compare("!")==0 && p.size()>=0 ) {
00428 if (p.size()>0) p = p.substr(0,p.size()-1) ;
00429 }else{
00430 if(p.size() < maxl && tp.compare("*")!=0) {
00431 p +=tp ;
00432 }
00433
00434 }
00435
00436 }
00437 buttmap = 0 ;
00438 dumpSurface(keypad) ;
00439 d->clearScreen() ;
00440 return p ;
00441
00442 }
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454 bool isAnswerCorrect(string test , string answer , int mode){
00455
00456 if(mode == 0 && answer.compare(test)==0) return true ;
00457
00458 if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00459
00460 if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00461
00462 return false;
00463 }
00464
00465
00466
00467 int addArgument(const string st,const string delim="="){
00468 int i = st.find(delim) ;
00469 argMap[st.substr(0,i)] = st.substr(i+1);
00470
00471 return 0 ;
00472 }
00473
00474 std::string getArgumentValue(string arg){
00475 return argMap[arg] ;
00476 }
00477
00478 std::string getUsageComment(){
00479
00480 string com = string("\nlist of arguments : \n");
00481
00482 com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00483 com += "\nmemo=[a_string_without_white_space]\n";
00484 com += "\nstring-size=[>0](the size of string){default=5} \n";
00485 com += "\nsubject=[subject_name] \n" ;
00486 com += "\nnum-of-a-sorting-trials=[>1](number of ascending trials){default=2}\n";
00487 com += "\nnum-of-d-sorting-trials=[>1](number of descending trials){default=2}\n";
00488 com += "\nnum-of-mem-trials=[>1](number of trials){default=10}\n";
00489 com += "\ndigit-onset=[>1] (number of frames that the string will remain onset ){default=10}\n";
00490 com += "\nalphabet=[a string of characters](a string of characters){default=0123456789}\n";
00491 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";
00492 com += "\ncue-wait-frames=[<0](number of frames to show the cue){default=0}\n";
00493 com += "\nmask=[y/n](whether present a mask after presentation, n for no, y for yes ){default=n}\n" ;
00494 com += "\nmask-onset-frames=[<0](number of frames that mask will be onset){default=0}\n";
00495 com += "\nwhite-space=[>0](the distance between digits in display){default=20}\n" ;
00496 com += "\ncue-type=[a/v](a for audio v for visual){default=v}\n";
00497 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00498 com += "\nfirst-stop=[a number](number of trials before the first recalibration){defalut=20}\n";
00499 com += "\nsecond-stop=[a number](number of trials before the second recalibration){defalut=40}\n";
00500 com += "\nthird-stop=[a number](number of trials before the third recalibration){defalut=60}\n";
00501 com += "\nasc-cue-sound-file=[file name for ascending cue operation]{defualt=sine.wav}\n";
00502 com += "\ndesc-cue-sound-file=[file name for ascending cue operation]{defualt=square.wav}\n";
00503 return com ;
00504 }
00505
00506
00507 void displayWholeNumber(string s , int onsetTime , int wsd){
00508 int x = (d->getWidth()-s.size()*wsd)/2 ;
00509 int y = (d->getHeight())/2 -10;
00510 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00511 textIm.clear(PixRGB<byte>(128,128,128));
00512 for( uint k = 0 ; k < s.size() ; k++ ){
00513
00514 writeText(textIm, Point2D<int>(x+k*wsd,y),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00515 }
00516 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00517 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00518 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00519 dumpSurface(surf);
00520 d->waitFrames(onsetTime);
00521 d->clearScreen() ;
00522 }
00523
00524 void displayWholeNumberVertically(string s , int onsetTime , int wsd){
00525 int x = (d->getWidth())/2 ;
00526 int y = (d->getHeight()-s.size()*wsd)/2 ;
00527 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00528 textIm.clear(PixRGB<byte>(128,128,128));
00529 for( uint k = 0 ; k < s.size() ; k++ ){
00530
00531 writeText(textIm, Point2D<int>(x,y+k*wsd),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00532 }
00533 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00534 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00535 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00536 dumpSurface(surf);
00537 d->waitFrames(onsetTime);
00538 d->clearScreen() ;
00539 }
00540
00541 void displayRandom(string s , int onsetTime){
00542 for( uint k = 0 ; k < s.size() ; k++ ){
00543 int x = 9*d->getWidth()/20 + rand()%(d->getWidth()/10);
00544 int y = 9*d->getHeight()/20 + rand()%(d->getHeight()/10) ;
00545 d->displayText(s.substr(k,1),Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00546 d->waitFrames(onsetTime);
00547 d->clearScreen() ;
00548 }
00549 }
00550
00551 void displayLinear(string s , int onsetTime){
00552 int x = (d->getWidth()-s.size()*10)/2 ;
00553 int y = d->getHeight()/2 - 10;
00554 for( uint k = 0 ; k < s.size() ; k++ ){
00555 d->displayText(s.substr(k,1),Point2D<int>(x+k*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00556 d->waitFrames(onsetTime);
00557 d->clearScreen() ;
00558 }
00559 }
00560
00561 void displayLinearReverse(string s , int onsetTime){
00562 int x = (d->getWidth()-s.size()*10)/2 ;
00563 int y = d->getHeight()/2 - 10;
00564 for( uint k = 0 ; k < s.size() ; k++ ){
00565 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) ;
00566 d->waitFrames(onsetTime);
00567 d->clearScreen() ;
00568 }
00569 }
00570 void displayLinearRandom(string s , int onsetTime){
00571 int x = (d->getWidth()-s.size()*10)/2 ;
00572 int y = d->getHeight()/2 - 10;
00573 for( uint k = 0 ; k < s.size() ; k++ ){
00574 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) ;
00575 d->waitFrames(onsetTime);
00576 d->clearScreen() ;
00577 }
00578 }
00579
00580 void displayLinearRandomVertically(string s , int onsetTime){
00581 int x = (d->getWidth())/2 ;
00582 int y = (d->getHeight()-s.size()*10)/2 - 10;
00583 for( uint k = 0 ; k < s.size() ; k++ ){
00584 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) ;
00585 d->waitFrames(onsetTime);
00586 d->clearScreen() ;
00587 }
00588 }
00589
00590 void displayLinearRandomNoRepeating(string s , int onsetTime){
00591 int x = (d->getWidth()-s.size()*10)/2 ;
00592 int y = d->getHeight()/2 - 10;
00593 for( uint k = 0 ; k < s.size() ; k++ ){
00594 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) ;
00595 d->waitFrames(onsetTime);
00596 d->clearScreen() ;
00597 }
00598 }
00599
00600
00601 void showMask(int frames, string alphabet="0123456789"){
00602 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00603 PixRGB<byte> bgcolor = PixRGB<byte>(128,128,128);
00604 PixRGB<byte> txtcolor = PixRGB<byte>(0,0,0);
00605 textIm.clear(bgcolor);
00606 for(int i = 0 ; i < 800 ; i++)
00607 writeText(textIm, Point2D<int>((int)random()%(d->getWidth()),(int)random()%(d->getHeight())),alphabet.substr(random()%(int)alphabet.size(),1).c_str(),txtcolor,bgcolor);
00608 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00609 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00610 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00611 d->waitFrames(frames) ;
00612 d->clearScreen();
00613 dumpSurface(surf) ;
00614 }
00615
00616
00617 vector<string> getAll_34012(string al="0123456789"){
00618 string tmp;
00619 vector<string> outVector ;
00620 for(int i0=0 ;i0<10 ;i0++ ){
00621 for( int i1=i0+2;i1<10 ; i1++ ){
00622 for( int i2=i1+2 ;i2<10 ; i2++){
00623 for( int i3=i2+1 ; i3 <10 ; i3++ ){
00624 for( int i4=i3+2; i4 < 10 ; i4++){
00625 tmp = al.substr(i3,1)+al.substr(i4,1)+al.substr(i0,1)+al.substr(i1,1)+al.substr(i2,1);
00626 outVector.push_back(tmp);
00627 }
00628 }
00629 }
00630 }
00631 }
00632 return outVector ;
00633 }
00634
00635 vector<string> getAll_21043(string al="0123456789"){
00636 string tmp;
00637 vector<string> outVector ;
00638 for(int i0=0 ;i0<10 ;i0++ ){
00639 for( int i1=i0+2;i1<10 ; i1++ ){
00640 for( int i2=i1+2 ;i2<10 ; i2++){
00641 for( int i3=i2+1 ; i3 <10 ; i3++ ){
00642 for( int i4=i3+2; i4 < 10 ; i4++){
00643 tmp = al.substr(i2,1)+al.substr(i1,1)+al.substr(i0,1)+al.substr(i4,1)+al.substr(i3,1);
00644 outVector.push_back(tmp);
00645 }
00646 }
00647 }
00648 }
00649 }
00650 return outVector ;
00651 }
00652 vector<string> getAll_41230(string al="0123456789"){
00653 string tmp;
00654 vector<string> outVector ;
00655 for(uint i0=0 ;i0<al.size() ;i0++ ){
00656 for( uint i1=i0+1;i1<al.size() ; i1++ ){
00657 for( uint i2=i1+2 ;i2<al.size() ; i2++){
00658 for( uint i3=i2+2 ; i3 <al.size() ; i3++ ){
00659 for( uint i4=i3+1; i4 < al.size() ; i4++){
00660 tmp = al.substr(i4,1)+al.substr(i1,1)+al.substr(i2,1)+al.substr(i3,1)+al.substr(i0,1);
00661 outVector.push_back(tmp);
00662 }
00663 }
00664 }
00665 }
00666 }
00667 return outVector ;
00668 }
00669
00670 vector<string> getAll_03214(string al="0123456789"){
00671 string tmp;
00672 vector<string> outVector ;
00673 for(uint i0=0 ;i0<al.size() ;i0++ ){
00674 for( uint i1=i0+1;i1<al.size() ; i1++ ){
00675 for( uint i2=i1+2 ;i2<al.size() ; i2++){
00676 for( uint i3=i2+2 ; i3 <al.size() ; i3++ ){
00677 for( uint i4=i3+1; i4 < al.size() ; i4++){
00678 tmp = al.substr(i0,1)+al.substr(i3,1)+al.substr(i2,1)+al.substr(i1,1)+al.substr(i4,1);
00679 outVector.push_back(tmp);
00680 }
00681 }
00682 }
00683 }
00684 }
00685 return outVector ;
00686 }
00687
00688 extern "C" int main(const int argc, char** argv)
00689 {
00690
00691 MYLOGVERB = LOG_INFO;
00692
00693 argMap["experiment"]="working memory single task - sorting";
00694 argMap["logfile"]="psycho-sorting-const.psy" ;
00695 argMap["string-size"]="5" ;
00696 argMap["subject"]="" ;
00697 argMap["memo"]="" ;
00698 argMap["digit-onset"]="10" ;
00699 argMap["alphabet"]="0123456789";
00700 argMap["mode"]="1" ;
00701 argMap["cue-wait-frames"]="0" ;
00702 argMap["mask"]="n" ;
00703 argMap["cue-onset-frames"] = "3" ;
00704 argMap["white-space"] = "20" ;
00705 argMap["cue-type"] = "v" ;
00706 argMap["sound-dir"]="..";
00707 argMap["num-of-a-sorting-trials"] = "2" ;
00708 argMap["num-of-d-sorting-trials"] = "2" ;
00709 argMap["num-of-mem-trials"] = "2" ;
00710 argMap["first-stop"]="20";
00711 argMap["second-stop"]="40";
00712 argMap["third-stop"] = "60";
00713 argMap["asc-cue-sound-file"]="sine.wav";
00714 argMap["desc-cue-sound-file"]="square.wav";
00715 manager.addSubComponent(d);
00716 nub::soft_ref<EventLog> el(new EventLog(manager));
00717 manager.addSubComponent(el);
00718 d->setEventLog(el);
00719 nub::soft_ref<EyeTrackerConfigurator>
00720 etc(new EyeTrackerConfigurator(manager));
00721 manager.addSubComponent(etc);
00722
00723 if (manager.parseCommandLine(argc, argv,
00724 "at least one argument needed", 1, -1)==false){
00725 cout<<getUsageComment()<<endl;
00726 return(1);
00727 }
00728
00729 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00730 addArgument(manager.getExtraArg(i),std::string("=")) ;
00731 }
00732
00733 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00734 manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00735 nub::soft_ref<EyeTracker> eyet = etc->getET();
00736 d->setEyeTracker(eyet);
00737 eyet->setEventLog(el);
00738
00739
00740
00741 manager.start();
00742 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00743
00744 d->clearScreen();
00745 d->displayISCANcalib();
00746 d->waitForMouseClick();
00747 d->displayText("Here the experiment starts! click to start!");
00748 d->waitForMouseClick();
00749 d->clearScreen();
00750
00751 int mode = atoi(argMap["mode"].c_str());
00752 vector<long> correctAnswersTiming;
00753 vector<long> incorrectAnswersTiming;
00754 vector<long> allTiming ;
00755 int correctMemory = 0 ;
00756 int incorrectMemory = 0 ;
00757 int correctAsc = 0 ;
00758 int incorrectAsc = 0 ;
00759 int correctDes = 0 ;
00760 int incorrectDes = 0 ;
00761 int stringSize = atoi(argMap["string-size"].c_str());
00762 int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00763 int cue_wait_frames = atoi(argMap["cue-wait-frames"].c_str()) ;
00764 int mask_onset_frames = atoi(argMap["mask-onset-frames"].c_str()) ;
00765 int white_sapece_distance = atoi(argMap["white-space"].c_str());
00766 int num_of_a_sorting_task = atoi(argMap["num-of-a-sorting-trials"].c_str()) ;
00767 int num_of_d_sorting_task = atoi(argMap["num-of-d-sorting-trials"].c_str()) ;
00768 int num_of_mem_task = atoi(argMap["num-of-mem-trials"].c_str()) ;
00769 int first_stop = atoi(argMap["first-stop"].c_str());
00770 int second_stop = atoi(argMap["second-stop"].c_str());
00771 int third_stop = atoi(argMap["third-stop"].c_str());
00772 string alphabet = argMap["alphabet"];
00773
00774 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00775 int cl = d->waitForMouseClick();
00776 if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00777 d->clearScreen() ;
00778
00779 map<int,Mix_Music*> audio_map ;
00780 map<string,int> charmap ;
00781 map<int,string> charinvmap ;
00782 Mix_Music* recallCueMusic = NULL;
00783 Mix_Music* sortCueMusic = NULL;
00784 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00785 LINFO( "did not open the mix-audio") ;
00786 return -1 ;
00787 }
00788 string str = argMap["sound-dir"]+"/"+argMap["asc-cue-sound-file"] ;
00789 recallCueMusic = Mix_LoadMUS(str.c_str());
00790 if(recallCueMusic==NULL) cout<<"not a 16 bit wav file "<<str<<endl;
00791 str = argMap["sound-dir"]+"/"+argMap["desc-cue-sound-file"] ;
00792 sortCueMusic = Mix_LoadMUS(str.c_str());
00793 if(sortCueMusic==NULL) cout<<"not a 16 bit wav file "<<str<<endl;
00794 if(argMap["cue-type"].compare("a")==0){
00795
00796 for(uint i = 0; i < alphabet.size() ; i++){
00797 string str = argMap["sound-dir"]+"/"+alphabet.substr(i,1)+".wav";
00798 audio_map[i]=Mix_LoadMUS(str.c_str());
00799 if(audio_map[i]==NULL) cout<<"not a 16 bit wav file "<<str<<endl;
00800 charmap[alphabet.substr(i,1)]=i;
00801 charinvmap[i]=alphabet.substr(i,1) ;
00802 }
00803 }
00804 vector<int>* taskVector = new vector<int>();
00805 for(int i = 0 ; i < (int)(num_of_a_sorting_task/2) ; i++) {
00806 taskVector->push_back(1);
00807 taskVector->push_back(2);
00808 }
00809 for(int i = 0 ; i < (int)(num_of_d_sorting_task/2) ; i++) {
00810 taskVector->push_back(3);
00811 taskVector->push_back(4);
00812 }
00813 vector<string> a_41230 = getAll_41230(alphabet);
00814 vector<string> a_03214 = getAll_03214(alphabet);
00815 vector<string> d_41230 = getAll_41230(alphabet);
00816 vector<string> d_03214 = getAll_03214(alphabet);
00817 scramble(a_41230);
00818 scramble(a_03214);
00819 scramble(d_41230);
00820 scramble(d_03214);
00821 int ind1 = 0 ; int ind2 = 0 ; int ind3 = 0 ;int ind4 = 0 ;
00822 for(int i = 0 ; i < num_of_mem_task ; i++) taskVector->push_back(0);
00823 scramble(*taskVector);
00824 for( int r = 0 ; (int)r < (int)taskVector->size() ; r++ ){
00825
00826 if(r==first_stop || r==second_stop || r==third_stop){
00827 d->displayText("YOU MAY STOP HERE TO TAKE A SHORT BRAKE!");
00828 d->waitForMouseClick();
00829 d->displayText("incorrect memory recalls="+stringify(incorrectMemory)+" incorrect ascending sorting:"+stringify(incorrectAsc) + " incorrect descencing sorting"+ stringify(incorrectDes) );
00830 d->waitForMouseClick();
00831 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00832 int cl = d->waitForMouseClick();
00833 if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00834 d->clearScreen() ;
00835 }
00836
00837 int task = taskVector->at(r) ;
00838 d->pushEvent("**************************************") ;
00839 d->showCursor(true);
00840 d->displayText("click one of the mouse buttons to start!");
00841 d->waitForMouseClick() ;
00842 string testString ;
00843 testString = getARandomString(stringSize,alphabet);
00844 switch( task ){
00845 case 1 : testString = a_41230.at(ind1);ind1++;break ;
00846 case 2 : testString = a_03214.at(ind2);ind2++;break ;
00847 case 3 : testString = d_41230.at(ind3);ind3++;break ;
00848 case 4 : testString = d_03214.at(ind4);ind4++;break ;
00849 }
00850 d->clearScreen() ;
00851 d->displayFixationBlink();
00852 if(argMap["cue-type"].compare("a")==0){
00853 for(int i = 0 ; i < (int)testString.size(); i++){
00854 if( Mix_PlayMusic( audio_map[charmap[testString.substr(i,1)]], 0 ) == -1 ) { return 1; }
00855 while( Mix_PlayingMusic() == 1 ){}
00856 d->waitFrames(onsetDel);
00857 }
00858 }else{
00859 switch( mode ){
00860 case 1 : displayWholeNumber(testString,onsetDel,white_sapece_distance);break ;
00861 case 2 : displayRandom(testString,onsetDel) ; break ;
00862 case 3 : displayLinear(testString,onsetDel) ; break ;
00863 case 4 : displayLinearRandom(testString,onsetDel) ; break ;
00864 case 5 : displayLinearReverse(testString,onsetDel) ; break ;
00865 case 6 : displayLinearRandomVertically(testString,onsetDel) ; break ;
00866 case 7 : displayWholeNumberVertically(testString,onsetDel,white_sapece_distance) ; break ;
00867 }
00868 }
00869 d->displayFixation() ;
00870
00871 if(argMap["mask"].compare("y")==0) showMask(mask_onset_frames,argMap["alphabet"]);
00872 if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00873 d->displayFixation() ;
00874
00875
00876 if(task == 0 ) {d->displayRedDotFixation();d->waitFrames(10);}
00877 if(task == 1 || task ==2 ){if( Mix_PlayMusic( recallCueMusic, 0 ) == -1 ) { return 1; }
00878 while( Mix_PlayingMusic() == 1 ){}
00879 }
00880 if(task==3 || task==4){
00881 if( Mix_PlayMusic( sortCueMusic, 0 ) == -1 ) { return 1; }
00882 while( Mix_PlayingMusic() == 1 ){}
00883 }
00884
00885
00886
00887
00888 string imst ;
00889 if(task!=0){
00890 imst= "===== Showing image: def_"+stringify(task)+"_"+stringify(r)+"_"+testString+".png =====";
00891 d->pushEvent("the sequence for operation is : "+testString) ;
00892 d->pushEvent(imst);
00893 eyet->track(true);
00894 d->waitForMouseClick();
00895 eyet->track(false);
00896 d->pushEvent("task ends") ;
00897 string answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size());
00898 d->pushEvent("subject keyed : "+answer);
00899 if((task==1 || task==2) && answer.compare(ascSort(testString))==0){
00900 d->pushEvent("answer was correct");
00901 correctAsc++ ;
00902 }
00903 if((task==1 || task==2) && answer.compare(ascSort(testString))!=0){
00904 d->pushEvent("answer was incorrect");
00905 incorrectAsc++ ;
00906 d->displayText("!!!!");
00907 d->waitFrames(20);
00908 }
00909
00910 if((task==3 || task==4) && answer.compare(desSort(testString))==0){
00911 d->pushEvent("answer was correct");
00912 correctDes++;
00913 }
00914 if((task==3 || task==4) && answer.compare(desSort(testString))!=0){
00915 d->pushEvent("answer was incorrect");
00916 incorrectDes++;
00917 d->displayText("!!!!");
00918 d->waitFrames(20);
00919 }
00920
00921 }else{
00922 string answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size());
00923 d->pushEvent("subject keyed : "+answer);
00924 if(answer.compare(testString)==0){
00925 d->pushEvent("recall was correct");
00926 correctMemory++ ;
00927 }else{
00928 d->pushEvent("recall was incorrect");
00929 incorrectMemory++ ;
00930 d->displayText("!!!!");
00931 d->waitFrames(20);
00932 }
00933 }
00934
00935 }
00936 d->pushEvent("number of correct memory recall : "+ stringify(correctMemory)) ;
00937 d->pushEvent("number of incorrect memory recall : "+ stringify(incorrectMemory)) ;
00938 d->pushEvent("number of correct ascending sorting :"+stringify(correctAsc));
00939 d->pushEvent("number of incorrect ascending sorting :"+stringify(incorrectAsc));
00940 d->pushEvent("number of correct descending sorting :"+stringify(correctDes));
00941 d->pushEvent("number of incorrect descending sorting :"+stringify(incorrectDes));
00942 d->clearScreen();
00943 d->displayText("Experiment complete. Thank you!");
00944 d->waitForMouseClick();
00945 taskVector = 0 ;
00946
00947 manager.stop();
00948
00949
00950
00951 return 0;
00952 }
00953
00954 #endif // INVT_HAVE_LIBSDL_IMAGE
00955