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-Spatial-Memory");
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
00097 template <class T> std::string stringify(T i)
00098 {
00099 ostringstream o ;
00100 o << i ;
00101 return o.str();
00102 }
00103
00104
00105 double getAvarage(vector<long> v){
00106 double f = 0.0 ;
00107 for( uint i = 0 ; i < v.size() ; i++ ){
00108 f += v[i] ;
00109 }
00110 if (v.size()!=0) return f/v.size() ;
00111 return -1 ;
00112 }
00113
00114 double getVariance(vector<long> v){
00115 double m = getAvarage(v);
00116 double var = 0.0 ;
00117 for( uint i = 0 ; i < v.size(); i++ ){
00118 var += (v[i]-m)*(v[i]-m) ;
00119 }
00120 if (v.size()!=0) return var/v.size() ;
00121 return -1 ;
00122 }
00123
00124 bool itIsInThere(int x , vector<int> bag){
00125 for( uint i=0 ; i < bag.size(); i++ ){
00126 if(x == bag[i]) return true ;
00127 }
00128 return false ;
00129 }
00130
00131
00132
00133
00134
00135
00136 string ascSort(string st)
00137 {
00138 string res = "" ;
00139 vector<string> v = vector<string>();
00140 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00141
00142 std::sort(v.begin(), v.end());
00143
00144 for ( uint i = 0 ; i < v.size() ; i++ ){
00145 res += v[i] ;
00146 }
00147 return res;
00148 }
00149
00150
00151
00152
00153
00154
00155
00156 string desSort(string st)
00157 {
00158 string res = "" ;
00159 vector<string> v = vector<string>();
00160 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00161 std::sort(v.begin(), v.end());
00162 std::reverse(v.begin(), v.end());
00163 for ( uint i = 0 ; i < v.size() ; i++ ){
00164 res += v[i] ;
00165 }
00166 return res;
00167 }
00168
00169
00170
00171
00172
00173
00174 string getARandomString(uint l, string alphabet="0123456789" ){
00175
00176 string test = string("") ;
00177 string retString ;
00178 test = "" ;
00179 string tp = string("") ;
00180 vector<int> pickedones = vector<int>() ;
00181 for(uint i = 0 ; i < l ; i++){
00182 int nd;
00183 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones)) ;
00184 pickedones.push_back(nd);
00185 tp = alphabet.substr(nd,1) ;
00186 test += tp ;
00187 }
00188 retString = test ;
00189 return retString ;
00190 }
00191
00192
00193
00194
00195
00196 string digitMemorizationTask(uint l, string alphabet="0123456789" , int displayFrame = 10 ){
00197 d->clearScreen() ;
00198 vector<int> pickedones = vector<int>() ;
00199 string test = string("") ;
00200 string tp = string("") ;
00201 for(uint i = 0 ; i < l ; i++){
00202 int nd;
00203 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00204 pickedones.push_back(nd);
00205 tp = alphabet.substr(nd,1) ;
00206 test += tp ;
00207 }
00208 d->displayText(test,true,0) ;
00209 d->waitFrames(displayFrame) ;
00210 d->clearScreen() ;
00211 return test ;
00212 }
00213
00214
00215
00216
00217
00218 void scramble(vector<string>& v){
00219 vector<string> tv = vector<string>() ;
00220 while(v.size()>0){
00221 tv.push_back(v[0]);
00222 v.erase(v.begin());
00223 }
00224 int i = 0 ;
00225 while(tv.size()>0){
00226 i = rand()%tv.size() ;
00227 v.push_back(tv[i]);
00228 tv.erase(tv.begin()+i);
00229 }
00230 }
00231
00232 void scramble(vector<int>& v){
00233 vector<int> tv = vector<int>() ;
00234 while(v.size()>0){
00235 tv.push_back(v[0]);
00236 v.erase(v.begin());
00237 }
00238 int i = 0 ;
00239 while(tv.size()>0){
00240 i = rand()%tv.size() ;
00241 v.push_back(tv[i]);
00242 tv.erase(tv.begin()+i);
00243 }
00244 }
00245
00246
00247
00248
00249 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){
00250 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00251 textIm.clear(bgcolor);
00252 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00253 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00254 Uint32 bc = d->getUint32color(bordercolor);
00255 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00256 SDL_Surface* blank =getABlankSurface(size.i , size.j);
00257 SDL_Rect clip;
00258 clip.x = 0 ;
00259 clip.y = 0 ;
00260 clip.w = size.i ;
00261 clip.h = size.j ;
00262 apply_surface(0,0,*surf,*blank,clip);
00263 dumpSurface(surf) ;
00264 return blank ;
00265 }
00266
00267
00268
00269
00270
00271
00272 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00273 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00274 SDL_Rect clip;
00275 clip.x=0;
00276 clip.y=0;
00277 int numofrows = alphabet.size()/3 +1;
00278 if(alphabet.size()%3 != 0 ) numofrows++ ;
00279 int numofcolumns = 3 ;
00280 clip.w= pad->w / numofcolumns ;
00281 clip.h = pad->h / numofrows ;
00282
00283
00284 for( int i = 0 ; i < numofrows*3 ; i++){
00285 SDL_Surface* but ;
00286 if((uint)i < alphabet.size()){
00287 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);
00288 }else{
00289 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);
00290 }
00291
00292 SDL_Rect cl ;
00293 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00294 cl.w = clip.w ;
00295 cl.h = clip.h ;
00296 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00297 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00298 dumpSurface(but);
00299 }
00300 SDL_Rect cl1 ;
00301 cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00302 cl1.w = clip.w ;
00303 cl1.h = clip.h ;
00304 buttmap["!"] = cl1 ;
00305 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);
00306 apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00307 dumpSurface(but);
00308 SDL_Rect cl2 ;
00309 cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00310 cl2.w = clip.w ;
00311 cl2.h = clip.h ;
00312 buttmap[" "] = cl2 ;
00313 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);
00314 apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00315 dumpSurface(but);
00316 SDL_Rect cl3 ;
00317 cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00318 cl3.w = clip.w ;
00319 cl3.h = clip.h ;
00320 buttmap["*"] = cl3 ;
00321 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);
00322 apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00323 dumpSurface(but);
00324 return pad ;
00325 }
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00336 int quit = 0 ;
00337 string s ;
00338 SDL_Event event ;
00339 while( quit!=2 ){
00340 while( SDL_PollEvent( &event ) ) {
00341 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){
00342 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00343 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) {
00344 quit = 2 ;
00345 s = it->first ;
00346 break;
00347 }
00348
00349 }
00350 }
00351
00352 }
00353 }
00354 return s ;
00355
00356 }
00357
00358
00359
00360
00361
00362
00363
00364 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 , string message=""){
00365 d->showCursor(true) ;
00366
00367 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00368
00369 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00370
00371 SDL_Rect offset ;
00372 offset.x = (d->getWidth() - keypad->w) /2;
00373 offset.y = (d-> getHeight() - keypad->h) /2;
00374
00375 SDL_Surface* msgp = getButtonImage(message ,PixRGB<byte>(195,60,12) ,PixRGB<byte>(127,127,127) ,Point2D<int>(d->getWidth()/6,d->getHeight() /15) ,PixRGB<byte>(127,127,127) , 4) ;
00376 SDL_Rect msgoffs ; msgoffs.x = (d->getWidth() - msgp->w) /2 ; msgoffs.y = 2*d->getHeight()/9 ;
00377 d->displaySDLSurfacePatch(msgp , &msgoffs , NULL , -2 , false ,true ) ;
00378 dumpSurface(msgp) ;
00379
00380 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00381
00382 string p = string("") ;
00383
00384 string tp = string("");
00385
00386 while( tp.compare("*")!=0 ){
00387
00388 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) ;
00389 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00390 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00391
00392 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00393 dumpSurface(dp) ;
00394 if(tp.compare("!")==0 && p.size()>=0 ) {
00395 if (p.size()>0) p = p.substr(0,p.size()-1) ;
00396 }else{
00397 if(p.size() < maxl && tp.compare("*")!=0) {
00398 p +=tp ;
00399 }
00400
00401 }
00402
00403 }
00404
00405 buttmap = 0 ;
00406 dumpSurface(keypad) ;
00407 d->clearScreen() ;
00408 return p ;
00409
00410 }
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 bool isAnswerCorrect(string test , string answer , int mode){
00423
00424 if(mode == 0 && answer.compare(test)==0) return true ;
00425
00426 if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00427
00428 if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00429
00430 return false;
00431 }
00432
00433
00434
00435 int addArgument(const string st,const string delim="="){
00436 int i = st.find(delim) ;
00437 argMap[st.substr(0,i)] = st.substr(i+1);
00438
00439 return 0 ;
00440 }
00441
00442 std::string getArgumentValue(string arg){
00443 return argMap[arg] ;
00444 }
00445
00446
00447 void displayWholeNumber(string s , int onsetTime , int wsd){
00448 int x = (d->getWidth()-s.size()*wsd)/2 ;
00449 int y = (d->getHeight())/2 -10;
00450 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00451 textIm.clear(PixRGB<byte>(128,128,128));
00452 for( uint k = 0 ; k < s.size() ; k++ ){
00453
00454 writeText(textIm, Point2D<int>(x+k*wsd,y),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00455 }
00456 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00457 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00458 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00459 dumpSurface(surf);
00460 d->waitFrames(onsetTime);
00461 d->clearScreen() ;
00462 }
00463
00464 void displayWholeNumberVertically(string s , int onsetTime , int wsd){
00465 int x = (d->getWidth())/2 ;
00466 int y = (d->getHeight()-s.size()*wsd)/2 ;
00467 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00468 textIm.clear(PixRGB<byte>(128,128,128));
00469 for( uint k = 0 ; k < s.size() ; k++ ){
00470
00471 writeText(textIm, Point2D<int>(x,y+k*wsd),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00472 }
00473 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00474 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00475 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00476 dumpSurface(surf);
00477 d->waitFrames(onsetTime);
00478 d->clearScreen() ;
00479 }
00480
00481 void displayRandom(string s , int onsetTime){
00482 for( uint k = 0 ; k < s.size() ; k++ ){
00483 int x = 9*d->getWidth()/20 + rand()%(d->getWidth()/10);
00484 int y = 9*d->getHeight()/20 + rand()%(d->getHeight()/10) ;
00485 d->displayText(s.substr(k,1),Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00486 d->waitFrames(onsetTime);
00487 d->clearScreen() ;
00488 }
00489 }
00490
00491 void displayLinear(string s , int onsetTime){
00492 int x = (d->getWidth()-s.size()*10)/2 ;
00493 int y = d->getHeight()/2 - 10;
00494 for( uint k = 0 ; k < s.size() ; k++ ){
00495 d->displayText(s.substr(k,1),Point2D<int>(x+k*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00496 d->waitFrames(onsetTime);
00497 d->clearScreen() ;
00498 }
00499 }
00500
00501 void displayLinearReverse(string s , int onsetTime){
00502 int x = (d->getWidth()-s.size()*10)/2 ;
00503 int y = d->getHeight()/2 - 10;
00504 for( uint k = 0 ; k < s.size() ; k++ ){
00505 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) ;
00506 d->waitFrames(onsetTime);
00507 d->clearScreen() ;
00508 }
00509 }
00510 void displayLinearRandom(string s , int onsetTime){
00511 int x = (d->getWidth()-s.size()*10)/2 ;
00512 int y = d->getHeight()/2 - 10;
00513 for( uint k = 0 ; k < s.size() ; k++ ){
00514 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) ;
00515 d->waitFrames(onsetTime);
00516 d->clearScreen() ;
00517 }
00518 }
00519
00520 void displayLinearRandomVertically(string s , int onsetTime){
00521 int x = (d->getWidth())/2 ;
00522 int y = (d->getHeight()-s.size()*10)/2 - 10;
00523 for( uint k = 0 ; k < s.size() ; k++ ){
00524 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) ;
00525 d->waitFrames(onsetTime);
00526 d->clearScreen() ;
00527 }
00528 }
00529
00530 void displayLinearRandomNoRepeating(string s , int onsetTime){
00531 int x = (d->getWidth()-s.size()*10)/2 ;
00532 int y = d->getHeight()/2 - 10;
00533 for( uint k = 0 ; k < s.size() ; k++ ){
00534 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) ;
00535 d->waitFrames(onsetTime);
00536 d->clearScreen() ;
00537 }
00538 }
00539
00540
00541 void showMask(int frames, string alphabet="0123456789"){
00542 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00543 PixRGB<byte> bgcolor = PixRGB<byte>(128,128,128);
00544 PixRGB<byte> txtcolor = PixRGB<byte>(0,0,0);
00545 textIm.clear(bgcolor);
00546 for(int i = 0 ; i < 200 ; i++)
00547 writeText(textIm, Point2D<int>((int)random()%(d->getWidth()),(int)random()%(d->getHeight())),alphabet.substr(random()%(int)alphabet.size(),1).c_str(),txtcolor,bgcolor);
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 d->waitFrames(frames) ;
00552 d->clearScreen();
00553 dumpSurface(surf) ;
00554 }
00555
00556 vector<int> spatial_memory_task(int onsetTime, int isd ,int rad=100 , int ma=45 ,int Ma=90){
00557
00558 int w = d->getWidth();
00559 int h = d->getHeight();
00560 int a1 = rand() % 360 ;
00561 int direction = (int)(((rand()%2)-0.5)/0.5);
00562 int a2 =a1 +direction*((rand() % (Ma-ma))+ma);
00563
00564 d->displayRedDotFixation(w/2+rad*cos(a1*3.1415/180),h/2 + rad*sin(a1*3.1415/180));
00565 d->waitFrames(onsetTime);
00566 d->clearScreen();
00567
00568 d->waitFrames(isd);
00569 d->displayRedDotFixation(w/2+rad*cos(a2*3.1415/180),h/2 + rad*sin(a2*3.1415/180));
00570 d->waitFrames(onsetTime);
00571 d->clearScreen();
00572 vector<int> angles;
00573 angles.push_back(a1);
00574 angles.push_back(a2);
00575 return angles ;
00576 }
00577
00578 int spatial_memory_retrival(vector<int> angles ,int rad = 100 ){
00579 int res=0 ;
00580 int flip = rand()%2;
00581 int w = d->getWidth();
00582 int h = d->getHeight();
00583 if(flip==0){
00584 d->displayRedDotFixation(w/2+rad*cos(angles.at(0)*3.1415/180),h/2 + rad*sin(angles.at(0)*3.1415/180));
00585 d->displayRedDotFixation(w/2+rad*cos(angles.at(1)*3.1415/180),h/2 + rad*sin(angles.at(1)*3.1415/180));
00586 }else{
00587 int a1=angles.at(0) % 360;
00588 int a2=angles.at(1) % 360;
00589 if (a2<a1) {
00590 int tmp = a2 ;
00591 a2=a1;
00592 a1=tmp;
00593 }
00594 int sflip=rand()%2;
00595 int del = ((rand()%15) + 30);
00596 if(sflip==0){
00597 a1=a1-del;
00598 }else{
00599 a2=a2+del;
00600 }
00601 d->displayRedDotFixation(w/2+rad*cos(a1*3.1415/180),h/2 + rad*sin(a1*3.1415/180));
00602 d->displayRedDotFixation(w/2+rad*cos(a2*3.1415/180),h/2 + rad*sin(a2*3.1415/180));
00603 }
00604 d->waitFrames(20);
00605 d->clearScreen();
00606 string ans = getDigitSequenceFromSubject("yn",1);
00607 if(flip==0){
00608 res = 0 ;
00609 if(ans.compare("y")==0) res=1;
00610 }else{
00611 res = 0 ;
00612 if(ans.compare("n")==0) res=1;
00613 }
00614 return res ;
00615 }
00616
00617 vector<int> executive_memory_task(Mix_Music* tone1 , Mix_Music* tone2 ,string initial_string,int counter_length, int min_tone_wait, int max_tone_wait ){
00618 int t1c = 0 ;
00619 int t2c = 0 ;
00620 vector<int> wFrames;
00621 vector<int> toneSequence ;
00622 vector<int> retVector ;
00623 map<int,string> strMap;
00624
00625 int flag=0;
00626 float milisum=0;
00627 do{
00628 int rtmp = rand()%(max_tone_wait - min_tone_wait) + min_tone_wait;
00629 milisum += rtmp*33.33 + 240;
00630 if(milisum > counter_length*33.33) {
00631 milisum = milisum -rtmp*33.33 - 240;
00632 flag=1;
00633 }else{
00634 wFrames.push_back(rtmp);
00635 toneSequence.push_back(rand()%2);
00636 }
00637 }while(flag==0);
00638 int lagFrames = (int)((counter_length - milisum)/33.33);
00639
00640 for(uint i = 0 ; i < wFrames.size() ; i++){
00641 d->pushEvent("will wait for "+stringify(wFrames[i]));
00642 if(toneSequence[i]==0){
00643 d->pushEvent("tone1 playing");
00644 t1c++;
00645 if(Mix_PlayMusic(tone1,0)==-1){return retVector;}
00646 while(Mix_PlayingMusic()==1){} ;
00647 }else{
00648 d->pushEvent("tone2 playing");
00649 t2c++ ;
00650 if(Mix_PlayMusic(tone2,0)==-1){return retVector;}
00651 while(Mix_PlayingMusic()==1){} ;
00652 }
00653 d->waitFrames(wFrames[i]);
00654 }
00655 d->waitFrames(lagFrames);
00656 retVector.push_back(t1c);
00657 retVector.push_back(t2c);
00658 d->clearScreen();
00659 d->displayFixation();
00660 return retVector ;
00661
00662 }
00663
00664
00665
00666 std::string getUsageComment(){
00667
00668 string com = string("\nlist of arguments : \n");
00669
00670 com += "\nlogfile=[logfilename.psy] {default = psycho-sm.psy}\n" ;
00671 com += "\nmemo=[a_string_without_white_space]\n";
00672 com += "\nstring-size=[>0](the size of counter string){default=4} \n";
00673 com += "\nsubject=[subject_name] \n" ;
00674 com += "\nnum-of-trials=[>1] (number of trials ) {default=10}\n";
00675 com += "\nalphabet=[a string of characters](a string of characters){default=abcdefghijklmnopqrstuvwxyz}\n";
00676 com += "\nmode=[1,2,3](1 for spatial memory task 2 for single counter task, 2 for concurrent task){default=1}\n";
00677 com += "\nsingle-dot-onset=[>1](number of frames that the single dot should be presented){default=16}\n";
00678 com += "\ndots_ISI=[>1](number of frames between dots presentations){default=16}\n";
00679 com += "\ndots_radius=[>1](the radius for circle of dots in pixel){default=100}\n";
00680 com += "\ndots_min_angle=[>0](minimum angle between dots on the circle){default=45}\n";
00681 com += "\ndots_max_angle=[>0] (maximum angle between dots on the circle){default=90}\n";
00682 com += "\nspatial-delay=[>0](number of frames for spatial memory task ){default=180}\n";
00683 com += "\n spatial-counter-ISI=[>1](numer of frames between last dot presentation and start of counter task){default=16}\n";
00684 com += "\n counter-length=[>1](total lenght of counter experiment in frames){default=460}\n";
00685 com += "\n counter-spatial-query-ISI=[>1](the delay between end of counter trail and start of spatial memory query in number of frames){default=16}\n";
00686 com += "\n spatial-query-length=[>1](the total length for showing the spatial memory test in number of frames){default=60}\n";
00687 com += "\n spatial-query-counter-query-ISI=[>1](number of frames between the unspeeded spatial memory query and showing the counter query){default=30}\n";
00688 com += "\n counter-query-length=[>1](number of frames for presenting the counter query){default=60}\n";
00689 com += "\n cue-onset-frames=[>1](){default=3}\n";;
00690 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00691 com += "\ntone1=[a valid file name](name of wav file without extension for tone 1){default=sin}\n";
00692 com += "\ntone2=[a valid file name](name of wav file without extension for tone 2){default=square}\n";
00693 com += "\ncue-file=[a valid file name](name of a wav file without extension for the audio cue){default=cue1}\n";
00694 com += "\nmin-tone-wait=[>1](minimum number of frames waiting on each tone){default=60}\n";
00695 com += "\nmax-tone-wait=[>1](maximum number of frames waiting on each tone){default=90}\n";
00696 return com ;
00697 }
00698
00699 extern "C" int main(const int argc, char** argv)
00700 {
00701
00702 MYLOGVERB = LOG_INFO;
00703
00704 argMap["experiment"]="spatial-memory-test";
00705 argMap["logfile"]="psycho-sm.psy" ;
00706 argMap["string-size"]="3" ;
00707 argMap["num-of-trials"]="10";
00708 argMap["subject"]="" ;
00709 argMap["memo"]="" ;
00710 argMap["single-dot-onset"]="16" ;
00711 argMap["dots-ISI"]="16";
00712 argMap["spatial-delay"]="180";
00713 argMap["spatial-counter-ISI"]="16";
00714 argMap["counter-length"]="460";
00715 argMap["counter-spatial-query-ISI"]="16";
00716 argMap["spatial-query-length"]="60";
00717 argMap["spatial-query-counter-query-ISI"]="30";
00718 argMap["counter-query-length"]="60";
00719 argMap["alphabet"]="0123456789";
00720 argMap["mode"]="1" ;
00721 argMap["cue-onset-frames"] = "3" ;
00722 argMap["sound-dir"]="..";
00723 argMap["tone1"]="sine";
00724 argMap["tone2"]="square";
00725 argMap["cue-file"]="cue1";
00726 argMap["min-tone-wait-1"]="40";
00727 argMap["max-tone-wait-1"]="60";
00728 argMap["min-tone-wait-2"]="90";
00729 argMap["max-tone-wait-2"]="110";
00730 argMap["dots_radius"]="100";
00731 argMap["dots_min_angle"]="45";
00732 argMap["dots_max_angle"]="90";
00733 manager.addSubComponent(d);
00734 nub::soft_ref<EventLog> el(new EventLog(manager));
00735 manager.addSubComponent(el);
00736 d->setEventLog(el);
00737 nub::soft_ref<EyeTrackerConfigurator>
00738 etc(new EyeTrackerConfigurator(manager));
00739 manager.addSubComponent(etc);
00740
00741 if (manager.parseCommandLine(argc, argv,
00742 "at least one argument needed", 1, -1)==false){
00743 cout<<getUsageComment()<<endl;
00744 return(1);
00745 }
00746
00747 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00748 addArgument(manager.getExtraArg(i),std::string("=")) ;
00749 }
00750
00751 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00752
00753
00754
00755
00756
00757
00758
00759 manager.start();
00760 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00761
00762 d->clearScreen();
00763 d->displayISCANcalib();
00764 d->waitForMouseClick();
00765 d->displayText("Here the experiment starts! click to start!");
00766 d->waitForMouseClick();
00767 d->clearScreen();
00768
00769
00770 string masterString=argMap["alphabet"];
00771
00772
00773 int numOfTests = atoi(argMap["num-of-trials"].c_str()) ;
00774 int stringSize = atoi(argMap["string-size"].c_str());
00775 int dots_ISI = atoi(argMap["dots-ISI"].c_str()) ;
00776 int dot_onset = atoi(argMap["single-dot-onset"].c_str());
00777 int dots_radius = atoi(argMap["dots_radius"].c_str());
00778 int dots_min_angle = atoi(argMap["dots_min_angle"].c_str());
00779 int dots_max_angle = atoi(argMap["dots_max_angle"].c_str());
00780 int mode = atoi(argMap["mode"].c_str());
00781 int counter_length = atoi(argMap["counter-length"].c_str());
00782 int min_tone_wait_1 = atoi(argMap["min-tone-wait-1"].c_str());
00783 int max_tone_wait_1 = atoi(argMap["max-tone-wait-1"].c_str());
00784 int min_tone_wait_2 = atoi(argMap["min-tone-wait-2"].c_str());
00785 int max_tone_wait_2 = atoi(argMap["max-tone-wait-2"].c_str());
00786
00787 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00788 int cl = d->waitForMouseClick();
00789 if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00790 d->clearScreen();
00791
00792
00793 Mix_Music* cueMusic = NULL;
00794 Mix_Music* tone1 = NULL;
00795 Mix_Music* tone2 = NULL;
00796 map<int,Mix_Music*> audio_map ;
00797 map<string,int> charmap ;
00798 map<int,string> charinvmap ;
00799
00800 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00801 LINFO( "did not open the mix-audio") ;
00802 return -1 ;
00803 }
00804
00805 for(uint i = 0; i < masterString.size() ; i++){
00806 string str = argMap["sound-dir"]+"/"+masterString.substr(i,1)+".wav";
00807 audio_map[i]=Mix_LoadMUS(str.c_str());
00808 charmap[masterString.substr(i,1)]=i;
00809 charinvmap[i]=masterString.substr(i,1) ;
00810 }
00811
00812 for( uint i=10;i<100 ;i++ ){
00813 charmap[stringify(i)]=i;
00814 charinvmap[i]=stringify(i);
00815 }
00816
00817 if(argMap["cue-type"].compare("a")==0){
00818 string str = argMap["sound-dir"]+"/"+argMap["cue-file"]+".wav" ;
00819 cueMusic = Mix_LoadMUS(str.c_str());
00820 }
00821
00822 string tmpstr = argMap["sound-dir"]+"/"+argMap["tone1"]+".wav";
00823 tone1 = Mix_LoadMUS(tmpstr.c_str());
00824 tmpstr = argMap["sound-dir"]+"/"+argMap["tone2"]+".wav";
00825 tone2 = Mix_LoadMUS(tmpstr.c_str());
00826
00827 int cr = numOfTests ;
00828 d->showCursor(true);
00829 d->displayText("click one of the mouse buttons to start!");
00830 d->waitForMouseClick() ;
00831 d->showCursor(false);
00832
00833 int correctSpatialMemory_1=0;
00834 int incorrectSpatialMemory_1=0;
00835 int correctSpatialMemory_2=0;
00836 int incorrectSpatialMemory_2=0;
00837 int correctCounting=0;
00838 int incorrectCounting=0;
00839 int missCounting=0;
00840 vector<int> tempoVector;
00841 for( int i = 0 ; i < numOfTests /2 ;i++ ){
00842 tempoVector.push_back(0);
00843 }
00844 for( int i = numOfTests /2 ; i < numOfTests ;i++ ){
00845 tempoVector.push_back(1);
00846 }
00847 scramble(tempoVector);
00848 cr=0;
00849 while( cr < numOfTests ){
00850 string inStr = getARandomString(stringSize,"234567");
00851 d->showCursor(false);
00852 d->clearScreen() ;
00853 d->pushEvent("**************************************") ;
00854 if(tempoVector.at(cr)==0) d->pushEvent("fast tempo");
00855 if(tempoVector.at(cr)==1) d->pushEvent("slow tempo");
00856 d->pushEvent("initial string :" + inStr);
00857 for(uint i = 0 ; i < inStr.size(); i++){
00858 d->pushEvent("playing character "+inStr.substr(i,1));
00859 if(Mix_PlayMusic(audio_map[charmap[inStr.substr(i,1)]],0)==-1){return 1;}
00860 while(Mix_PlayingMusic()==1){} ;
00861 d->pushEvent("ended playing character "+inStr.substr(i,1));
00862 }
00863 d->waitFrames(60);
00864 d->displayFixation();
00865 d->waitFrames(10);
00866 d->clearScreen() ;
00867 vector<int> angles = spatial_memory_task(dot_onset,dots_ISI,dots_radius,dots_min_angle,dots_max_angle);
00868 d->pushEvent("dots showed at these angles :"+ stringify(angles.at(0))+" and " + stringify(angles.at(1)));
00869 d->waitFrames(10);
00870 d->displayFixation();
00871 vector<int> tonesVector;
00872 if(tempoVector.at(cr)==0)
00873 tonesVector = executive_memory_task( tone1 , tone2 , inStr, counter_length, min_tone_wait_1, max_tone_wait_1 );
00874 if(tempoVector.at(cr)==1)
00875 tonesVector = executive_memory_task( tone1 , tone2 , inStr, counter_length, min_tone_wait_2, max_tone_wait_2 );
00876 string newStr ;
00877 if (stringSize == 2)
00878 newStr = charinvmap[charmap[inStr.substr(0,1)]+tonesVector.at(0)]+charinvmap[charmap[inStr.substr(inStr.size()-1,1)]+tonesVector.at(1)];
00879 if (stringSize>2)
00880 newStr = charinvmap[charmap[inStr.substr(0,1)]+tonesVector.at(0)]+inStr.substr(1,inStr.size()-2)+charinvmap[charmap[inStr.substr(inStr.size()-1,1)]+tonesVector.at(1)];
00881 if(mode==1 || mode==3){
00882 int spMemAns = spatial_memory_retrival(angles,dots_radius);
00883 if(tempoVector.at(cr)==0){
00884 switch( spMemAns ){
00885 case 0 : incorrectSpatialMemory_1++;d->pushEvent("incorrect spatial memory recall");break;
00886 case 1 : correctSpatialMemory_1++;d->pushEvent("correct spatial memory recall");break;
00887 }
00888 }
00889
00890 if(tempoVector.at(cr)==1){
00891 switch( spMemAns ){
00892 case 0 : incorrectSpatialMemory_2++;d->pushEvent("incorrect spatial memory recall");break;
00893 case 1 : correctSpatialMemory_2++;d->pushEvent("correct spatial memory recall");break;
00894 }
00895 }
00896 }
00897
00898
00899 if(mode ==1){
00900
00901 string ans1 = getDigitSequenceFromSubject(masterString,1,"first digit");
00902 d->pushEvent("subject keyed:" + ans1 + " for first digit");
00903 string ans2 = getDigitSequenceFromSubject(masterString,1,"second digit");
00904 d->pushEvent("subject keyed:" + ans2 + " for second digit");
00905
00906 if(ans1.compare(inStr.substr(0,1))==0 && ans2.compare(inStr.substr(inStr.size()-1,1))==0 ) {
00907 correctCounting++;
00908 }else{
00909 incorrectCounting++ ;
00910 }
00911
00912 }
00913
00914 if(mode ==2 || mode==3){
00915 int sineCounter = tonesVector.at(0)+atoi(inStr.substr(0,1).c_str());
00916 int squareCounter = tonesVector.at(1)+atoi(inStr.substr(inStr.size()-1,1).c_str());
00917 d->pushEvent("sine signal counter is :"+stringify(sineCounter));
00918 d->pushEvent("square signal counter is :"+stringify(squareCounter));
00919 string ans1 = getDigitSequenceFromSubject(masterString,2,"soft tone counter");
00920 d->pushEvent("subject keyed:" + ans1 + " for sine counter");
00921 string ans2 = getDigitSequenceFromSubject(masterString,2,"rough tone counter");
00922 d->pushEvent("subject keyed:" + ans2 + " for square counter");
00923 d->pushEvent("trial misscounting: " + stringify(abs(atoi(ans1.c_str()) - sineCounter) + abs(atoi(ans2.c_str()) - squareCounter)));
00924 missCounting += abs(atoi(ans1.c_str()) - sineCounter) + abs(atoi(ans2.c_str()) - squareCounter);
00925
00926 }
00927 cr++;
00928 }
00929 d->pushEvent("correct spatial memory (fast tempo): " +stringify(correctSpatialMemory_1));
00930 d->pushEvent("incorrect spatial memory (fast tempo): " +stringify(incorrectSpatialMemory_1));
00931 d->pushEvent("correct spatial memory (slow tempo): " +stringify(correctSpatialMemory_2));
00932 d->pushEvent("incorrect spatial memory (slow tempo): " +stringify(incorrectSpatialMemory_2));
00933 d->pushEvent("correct counting: " +stringify(correctCounting));
00934 d->pushEvent("incorrect counting: " +stringify(incorrectCounting));
00935 d->pushEvent("total misscounting: "+stringify(missCounting));
00936 d->displayText("Experiment complete. Thank you!");
00937 d->waitForMouseClick();
00938
00939
00940 manager.stop();
00941
00942
00943
00944 return 0;
00945 }
00946
00947 #endif // INVT_HAVE_LIBSDL_IMAGE
00948