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
00233
00234
00235
00236 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){
00237 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00238 textIm.clear(bgcolor);
00239 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00240 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00241 Uint32 bc = d->getUint32color(bordercolor);
00242 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00243 SDL_Surface* blank =getABlankSurface(size.i , size.j);
00244 SDL_Rect clip;
00245 clip.x = 0 ;
00246 clip.y = 0 ;
00247 clip.w = size.i ;
00248 clip.h = size.j ;
00249 apply_surface(0,0,*surf,*blank,clip);
00250 dumpSurface(surf) ;
00251 return blank ;
00252 }
00253
00254
00255
00256
00257
00258
00259 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00260 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00261 SDL_Rect clip;
00262 clip.x=0;
00263 clip.y=0;
00264 int numofrows = alphabet.size()/3 +1;
00265 if(alphabet.size()%3 != 0 ) numofrows++ ;
00266 int numofcolumns = 3 ;
00267 clip.w= pad->w / numofcolumns ;
00268 clip.h = pad->h / numofrows ;
00269
00270
00271 for( int i = 0 ; i < numofrows*3 ; i++){
00272 SDL_Surface* but ;
00273 if((uint)i < alphabet.size()){
00274 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);
00275 }else{
00276 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);
00277 }
00278
00279 SDL_Rect cl ;
00280 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00281 cl.w = clip.w ;
00282 cl.h = clip.h ;
00283 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00284 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00285 dumpSurface(but);
00286 }
00287 SDL_Rect cl1 ;
00288 cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00289 cl1.w = clip.w ;
00290 cl1.h = clip.h ;
00291 buttmap["!"] = cl1 ;
00292 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);
00293 apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00294 dumpSurface(but);
00295 SDL_Rect cl2 ;
00296 cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00297 cl2.w = clip.w ;
00298 cl2.h = clip.h ;
00299 buttmap[" "] = cl2 ;
00300 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);
00301 apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00302 dumpSurface(but);
00303 SDL_Rect cl3 ;
00304 cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00305 cl3.w = clip.w ;
00306 cl3.h = clip.h ;
00307 buttmap["*"] = cl3 ;
00308 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);
00309 apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00310 dumpSurface(but);
00311 return pad ;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00323 int quit = 0 ;
00324 string s ;
00325 SDL_Event event ;
00326 while( quit!=2 ){
00327 while( SDL_PollEvent( &event ) ) {
00328 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){
00329 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00330 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) {
00331 quit = 2 ;
00332 s = it->first ;
00333 break;
00334 }
00335
00336 }
00337 }
00338
00339 }
00340 }
00341 return s ;
00342
00343 }
00344
00345
00346
00347
00348
00349
00350
00351 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00352 d->showCursor(true) ;
00353
00354 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00355
00356 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00357
00358 SDL_Rect offset ;
00359 offset.x = (d->getWidth() - keypad->w) /2;
00360 offset.y = (d-> getHeight() - keypad->h) /2;
00361
00362 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00363
00364 string p = string("") ;
00365
00366 string tp = string("");
00367
00368 while( tp.compare("*")!=0 ){
00369
00370 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) ;
00371 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00372 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00373
00374 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00375 dumpSurface(dp) ;
00376 if(tp.compare("!")==0 && p.size()>=0 ) {
00377 if (p.size()>0) p = p.substr(0,p.size()-1) ;
00378 }else{
00379 if(p.size() < maxl && tp.compare("*")!=0) {
00380 p +=tp ;
00381 }
00382
00383 }
00384
00385 }
00386 buttmap = 0 ;
00387 dumpSurface(keypad) ;
00388 d->clearScreen() ;
00389 return p ;
00390
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403 bool isAnswerCorrect(string test , string answer , int mode){
00404
00405 if(mode == 0 && answer.compare(test)==0) return true ;
00406
00407 if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00408
00409 if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00410
00411 return false;
00412 }
00413
00414
00415
00416 int addArgument(const string st,const string delim="="){
00417 int i = st.find(delim) ;
00418 argMap[st.substr(0,i)] = st.substr(i+1);
00419
00420 return 0 ;
00421 }
00422
00423 std::string getArgumentValue(string arg){
00424 return argMap[arg] ;
00425 }
00426
00427
00428 void displayWholeNumber(string s , int onsetTime , int wsd){
00429 int x = (d->getWidth()-s.size()*wsd)/2 ;
00430 int y = (d->getHeight())/2 -10;
00431 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00432 textIm.clear(PixRGB<byte>(128,128,128));
00433 for( uint k = 0 ; k < s.size() ; k++ ){
00434
00435 writeText(textIm, Point2D<int>(x+k*wsd,y),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00436 }
00437 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00438 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00439 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00440 dumpSurface(surf);
00441 d->waitFrames(onsetTime);
00442 d->clearScreen() ;
00443 }
00444
00445 void displayWholeNumberVertically(string s , int onsetTime , int wsd){
00446 int x = (d->getWidth())/2 ;
00447 int y = (d->getHeight()-s.size()*wsd)/2 ;
00448 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00449 textIm.clear(PixRGB<byte>(128,128,128));
00450 for( uint k = 0 ; k < s.size() ; k++ ){
00451
00452 writeText(textIm, Point2D<int>(x,y+k*wsd),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00453 }
00454 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00455 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00456 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00457 dumpSurface(surf);
00458 d->waitFrames(onsetTime);
00459 d->clearScreen() ;
00460 }
00461
00462 void displayRandom(string s , int onsetTime){
00463 for( uint k = 0 ; k < s.size() ; k++ ){
00464 int x = 9*d->getWidth()/20 + rand()%(d->getWidth()/10);
00465 int y = 9*d->getHeight()/20 + rand()%(d->getHeight()/10) ;
00466 d->displayText(s.substr(k,1),Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00467 d->waitFrames(onsetTime);
00468 d->clearScreen() ;
00469 }
00470 }
00471
00472 void displayLinear(string s , int onsetTime){
00473 int x = (d->getWidth()-s.size()*10)/2 ;
00474 int y = d->getHeight()/2 - 10;
00475 for( uint k = 0 ; k < s.size() ; k++ ){
00476 d->displayText(s.substr(k,1),Point2D<int>(x+k*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00477 d->waitFrames(onsetTime);
00478 d->clearScreen() ;
00479 }
00480 }
00481
00482 void displayLinearReverse(string s , int onsetTime){
00483 int x = (d->getWidth()-s.size()*10)/2 ;
00484 int y = d->getHeight()/2 - 10;
00485 for( uint k = 0 ; k < s.size() ; k++ ){
00486 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) ;
00487 d->waitFrames(onsetTime);
00488 d->clearScreen() ;
00489 }
00490 }
00491 void displayLinearRandom(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+ (random()%s.size())*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 displayLinearRandomVertically(string s , int onsetTime){
00502 int x = (d->getWidth())/2 ;
00503 int y = (d->getHeight()-s.size()*10)/2 - 10;
00504 for( uint k = 0 ; k < s.size() ; k++ ){
00505 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) ;
00506 d->waitFrames(onsetTime);
00507 d->clearScreen() ;
00508 }
00509 }
00510
00511 void displayLinearRandomNoRepeating(string s , int onsetTime){
00512 int x = (d->getWidth()-s.size()*10)/2 ;
00513 int y = d->getHeight()/2 - 10;
00514 for( uint k = 0 ; k < s.size() ; k++ ){
00515 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) ;
00516 d->waitFrames(onsetTime);
00517 d->clearScreen() ;
00518 }
00519 }
00520
00521
00522 void showMask(int frames, string alphabet="0123456789"){
00523 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00524 PixRGB<byte> bgcolor = PixRGB<byte>(128,128,128);
00525 PixRGB<byte> txtcolor = PixRGB<byte>(0,0,0);
00526 textIm.clear(bgcolor);
00527 for(int i = 0 ; i < 200 ; i++)
00528 writeText(textIm, Point2D<int>((int)random()%(d->getWidth()),(int)random()%(d->getHeight())),alphabet.substr(random()%(int)alphabet.size(),1).c_str(),txtcolor,bgcolor);
00529 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00530 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00531 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00532 d->waitFrames(frames) ;
00533 d->clearScreen();
00534 dumpSurface(surf) ;
00535 }
00536
00537 vector<int> spatial_memory_task(int onsetTime, int isd ,int rad=100 , int ma=45 ,int Ma=90){
00538
00539 int w = d->getWidth();
00540 int h = d->getHeight();
00541 int a1 = rand() % 360 ;
00542 int direction = (int)(((rand()%2)-0.5)/0.5);
00543 int a2 =a1 +direction*((rand() % (Ma-ma))+ma);
00544
00545 d->displayRedDotFixation(w/2+rad*cos(a1*3.1415/180),h/2 + rad*sin(a1*3.1415/180));
00546 d->waitFrames(onsetTime);
00547 d->clearScreen();
00548
00549 d->waitFrames(isd);
00550 d->displayRedDotFixation(w/2+rad*cos(a2*3.1415/180),h/2 + rad*sin(a2*3.1415/180));
00551 d->waitFrames(onsetTime);
00552 d->clearScreen();
00553 vector<int> angles;
00554 angles.push_back(a1);
00555 angles.push_back(a2);
00556 return angles ;
00557 }
00558
00559 int spatial_memory_retrival(vector<int> angles ,int rad = 100 ){
00560 int res=0 ;
00561 int flip = rand()%2;
00562 int w = d->getWidth();
00563 int h = d->getHeight();
00564 if(flip==0){
00565 d->displayRedDotFixation(w/2+rad*cos(angles.at(0)*3.1415/180),h/2 + rad*sin(angles.at(0)*3.1415/180));
00566 d->displayRedDotFixation(w/2+rad*cos(angles.at(1)*3.1415/180),h/2 + rad*sin(angles.at(1)*3.1415/180));
00567 }else{
00568 int a1=angles.at(0) % 360;
00569 int a2=angles.at(1) % 360;
00570 if (a2<a1) {
00571 int tmp = a2 ;
00572 a2=a1;
00573 a1=tmp;
00574 }
00575 int sflip=rand()%2;
00576 int del = ((rand()%15) + 30);
00577 if(sflip==0){
00578 a1=a1-del;
00579 }else{
00580 a2=a2+del;
00581 }
00582 d->displayRedDotFixation(w/2+rad*cos(a1*3.1415/180),h/2 + rad*sin(a1*3.1415/180));
00583 d->displayRedDotFixation(w/2+rad*cos(a2*3.1415/180),h/2 + rad*sin(a2*3.1415/180));
00584 }
00585 d->waitFrames(20);
00586 d->clearScreen();
00587 string ans = getDigitSequenceFromSubject("yn");
00588 if(flip==0){
00589 res = 0 ;
00590 if(ans.compare("y")==0) res=1;
00591 }else{
00592 res = 0 ;
00593 if(ans.compare("n")==0) res=1;
00594 }
00595 return res ;
00596 }
00597
00598 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 ){
00599 int t1c = 0 ;
00600 int t2c = 0 ;
00601 vector<int> wFrames;
00602 vector<int> toneSequence ;
00603 vector<int> retVector ;
00604 map<int,string> strMap;
00605
00606 int flag=0;
00607 float milisum=0;
00608 do{
00609 int rtmp = rand()%(max_tone_wait - min_tone_wait) + min_tone_wait;
00610 milisum += rtmp*33.33 + 240;
00611 if(milisum > counter_length*33.33) {
00612 milisum = milisum -rtmp*33.33 - 240;
00613 flag=1;
00614 }else{
00615 wFrames.push_back(rtmp);
00616 toneSequence.push_back(rand()%2);
00617 }
00618 }while(flag==0);
00619 int lagFrames = (int)((counter_length - milisum)/33.33);
00620
00621 for(uint i = 0 ; i < wFrames.size() ; i++){
00622 d->pushEvent("will wait for "+stringify(wFrames[i]));
00623 d->waitFrames(wFrames[i]);
00624 if(toneSequence[i]==0){
00625 d->pushEvent("tone1 playing");
00626 t1c++;
00627 if(Mix_PlayMusic(tone1,0)==-1){return retVector;}
00628 while(Mix_PlayingMusic()==1){} ;
00629 }else{
00630 d->pushEvent("tone2 playing");
00631 t2c++ ;
00632 if(Mix_PlayMusic(tone2,0)==-1){return retVector;}
00633 while(Mix_PlayingMusic()==1){} ;
00634 }
00635 }
00636 d->waitFrames(lagFrames);
00637 retVector.push_back(t1c);
00638 retVector.push_back(t2c);
00639 d->clearScreen();
00640 d->displayFixation();
00641 return retVector ;
00642
00643 }
00644
00645
00646
00647 std::string getUsageComment(){
00648
00649 string com = string("\nlist of arguments : \n");
00650
00651 com += "\nlogfile=[logfilename.psy] {default = psycho-sm.psy}\n" ;
00652 com += "\nmemo=[a_string_without_white_space]\n";
00653 com += "\nstring-size=[>0](the size of counter string){default=4} \n";
00654 com += "\nsubject=[subject_name] \n" ;
00655 com += "\nnum-of-trials=[>1] (number of trials ) {default=10}\n";
00656 com += "\nalphabet=[a string of characters](a string of characters){default=abcdefghijklmnopqrstuvwxyz}\n";
00657 com += "\nmode=[1,2,3](1 for spatial memory task 2 for single counter task, 2 for concurrent task){default=1}\n";
00658 com += "\nsingle-dot-onset=[>1](number of frames that the single dot should be presented){default=16}\n";
00659 com += "\ndots_ISI=[>1](number of frames between dots presentations){default=16}\n";
00660 com += "\ndots_radius=[>1](the radius for circle of dots in pixel){default=100}\n";
00661 com += "\ndots_min_angle=[>0](minimum angle between dots on the circle){default=45}\n";
00662 com += "\ndots_max_angle=[>0] (maximum angle between dots on the circle){default=90}\n";
00663 com += "\nspatial-delay=[>0](number of frames for spatial memory task ){default=180}\n";
00664 com += "\n spatial-counter-ISI=[>1](numer of frames between last dot presentation and start of counter task){default=16}\n";
00665 com += "\n counter-length=[>1](total lenght of counter experiment in frames){default=460}\n";
00666 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";
00667 com += "\n spatial-query-length=[>1](the total length for showing the spatial memory test in number of frames){default=60}\n";
00668 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";
00669 com += "\n counter-query-length=[>1](number of frames for presenting the counter query){default=60}\n";
00670 com += "\n cue-onset-frames=[>1](){default=3}\n";;
00671 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00672 com += "\ntone1=[a valid file name](name of wav file without extension for tone 1){default=sin}\n";
00673 com += "\ntone2=[a valid file name](name of wav file without extension for tone 2){default=square}\n";
00674 com += "\ncue-file=[a valid file name](name of a wav file without extension for the audio cue){default=cue1}\n";
00675 com += "\nmin-tone-wait=[>1](minimum number of frames waiting on each tone){default=60}\n";
00676 com += "\nmax-tone-wait=[>1](maximum number of frames waiting on each tone){default=90}\n";
00677 return com ;
00678 }
00679
00680 extern "C" int main(const int argc, char** argv)
00681 {
00682
00683 MYLOGVERB = LOG_INFO;
00684
00685 argMap["experiment"]="spatial-memory-test";
00686 argMap["logfile"]="psycho-sm.psy" ;
00687 argMap["string-size"]="3" ;
00688 argMap["num-of-trials"]="10";
00689 argMap["subject"]="" ;
00690 argMap["memo"]="" ;
00691 argMap["single-dot-onset"]="16" ;
00692 argMap["dots-ISI"]="16";
00693 argMap["spatial-delay"]="180";
00694 argMap["spatial-counter-ISI"]="16";
00695 argMap["counter-length"]="460";
00696 argMap["counter-spatial-query-ISI"]="16";
00697 argMap["spatial-query-length"]="60";
00698 argMap["spatial-query-counter-query-ISI"]="30";
00699 argMap["counter-query-length"]="60";
00700 argMap["alphabet"]="abcdefghijklmnopqrstuvwxyz";
00701 argMap["mode"]="1" ;
00702 argMap["cue-onset-frames"] = "3" ;
00703 argMap["sound-dir"]="..";
00704 argMap["tone1"]="sine";
00705 argMap["tone2"]="square";
00706 argMap["cue-file"]="cue1";
00707 argMap["min-tone-wait"]="60";
00708 argMap["max-tone-wait"]="90";
00709 argMap["dots_radius"]="100";
00710 argMap["dots_min_angle"]="45";
00711 argMap["dots_max_angle"]="90";
00712 manager.addSubComponent(d);
00713 nub::soft_ref<EventLog> el(new EventLog(manager));
00714 manager.addSubComponent(el);
00715 d->setEventLog(el);
00716 nub::soft_ref<EyeTrackerConfigurator>
00717 etc(new EyeTrackerConfigurator(manager));
00718 manager.addSubComponent(etc);
00719
00720 if (manager.parseCommandLine(argc, argv,
00721 "at least one argument needed", 1, -1)==false){
00722 cout<<getUsageComment()<<endl;
00723 return(1);
00724 }
00725
00726 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00727 addArgument(manager.getExtraArg(i),std::string("=")) ;
00728 }
00729
00730 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00731
00732
00733
00734
00735
00736
00737
00738 manager.start();
00739 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00740
00741 d->clearScreen();
00742 d->displayISCANcalib();
00743 d->waitForMouseClick();
00744 d->displayText("Here the experiment starts! click to start!");
00745 d->waitForMouseClick();
00746 d->clearScreen();
00747
00748
00749 string masterString=argMap["alphabet"];
00750
00751
00752 int numOfTests = atoi(argMap["num-of-trials"].c_str()) ;
00753 int stringSize = atoi(argMap["string-size"].c_str());
00754 int dots_ISI = atoi(argMap["dots-ISI"].c_str()) ;
00755 int dot_onset = atoi(argMap["single-dot-onset"].c_str());
00756 int dots_radius = atoi(argMap["dots_radius"].c_str());
00757 int dots_min_angle = atoi(argMap["dots_min_angle"].c_str());
00758 int dots_max_angle = atoi(argMap["dots_max_angle"].c_str());
00759 int mode = atoi(argMap["mode"].c_str());
00760 int counter_length = atoi(argMap["counter-length"].c_str());
00761 int min_tone_wait = atoi(argMap["min-tone-wait"].c_str());
00762 int max_tone_wait = atoi(argMap["max-tone-wait"].c_str());
00763
00764 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00765 int cl = d->waitForMouseClick();
00766 if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00767 d->clearScreen();
00768
00769
00770 Mix_Music* cueMusic = NULL;
00771 Mix_Music* tone1 = NULL;
00772 Mix_Music* tone2 = NULL;
00773 map<int,Mix_Music*> audio_map ;
00774 map<string,int> charmap ;
00775 map<int,string> charinvmap ;
00776
00777 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00778 LINFO( "did not open the mix-audio") ;
00779 return -1 ;
00780 }
00781
00782 for(uint i = 0; i < masterString.size() ; i++){
00783 string str = argMap["sound-dir"]+"/"+masterString.substr(i,1)+".wav";
00784 audio_map[i]=Mix_LoadMUS(str.c_str());
00785 charmap[masterString.substr(i,1)]=i;
00786 charinvmap[i]=masterString.substr(i,1) ;
00787 }
00788
00789 if(argMap["cue-type"].compare("a")==0){
00790 string str = argMap["sound-dir"]+"/"+argMap["cue-file"]+".wav" ;
00791 cueMusic = Mix_LoadMUS(str.c_str());
00792 }
00793
00794 string tmpstr = argMap["sound-dir"]+"/"+argMap["tone1"]+".wav";
00795 tone1 = Mix_LoadMUS(tmpstr.c_str());
00796 tmpstr = argMap["sound-dir"]+"/"+argMap["tone2"]+".wav";
00797 tone2 = Mix_LoadMUS(tmpstr.c_str());
00798
00799 int cr = numOfTests ;
00800 d->showCursor(true);
00801 d->displayText("click one of the mouse buttons to start!");
00802 d->waitForMouseClick() ;
00803 d->showCursor(false);
00804
00805 int correctSpatialMemory=0;
00806 int incorrectSpatialMemory=0;
00807 int correctCounting=0;
00808 int incorrectCounting=0;
00809 int missCounting=0;
00810 cr=0;
00811 while( cr < numOfTests ){
00812 string inStr = getARandomString(stringSize,"cdfgh");
00813 d->showCursor(false);
00814 d->clearScreen() ;
00815 d->pushEvent("**************************************") ;
00816 d->pushEvent("initial string :" + inStr);
00817 for(uint i = 0 ; i < inStr.size(); i++){
00818 d->pushEvent("playing character "+inStr.substr(i,1));
00819 if(Mix_PlayMusic(audio_map[charmap[inStr.substr(i,1)]],0)==-1){return 1;}
00820 while(Mix_PlayingMusic()==1){} ;
00821 d->pushEvent("ended playing character "+inStr.substr(i,1));
00822 }
00823 d->waitFrames(60);
00824 d->displayFixation();
00825 d->waitFrames(10);
00826 d->clearScreen() ;
00827 vector<int> angles = spatial_memory_task(dot_onset,dots_ISI,dots_radius,dots_min_angle,dots_max_angle);
00828 d->pushEvent("dots showed at these angles :"+ stringify(angles.at(0))+" and " + stringify(angles.at(1)));
00829 d->waitFrames(10);
00830 d->displayFixation();
00831 vector<int> tonesVector = executive_memory_task( tone1 , tone2 , inStr, counter_length, min_tone_wait, max_tone_wait );
00832 string newStr ;
00833 if (stringSize == 2)
00834 newStr = charinvmap[charmap[inStr.substr(0,1)]+tonesVector.at(0)]+charinvmap[charmap[inStr.substr(inStr.size()-1,1)]+tonesVector.at(1)];
00835 if (stringSize>2)
00836 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)];
00837 if(mode==1 || mode==3){
00838 int spMemAns = spatial_memory_retrival(angles,dots_radius);
00839 switch( spMemAns ){
00840 case 0 : incorrectSpatialMemory++;break;
00841 case 1 : correctSpatialMemory++;break;
00842 }
00843 }
00844
00845 string ans = getDigitSequenceFromSubject(masterString);
00846 d->pushEvent("subject keyed:" + ans);
00847 if(mode ==1){
00848 if(ans.compare(inStr)==0) {
00849 correctCounting++;
00850 }else{
00851 incorrectCounting++ ;
00852 }
00853
00854 }
00855
00856 if(mode ==2 || mode==3){
00857 d->pushEvent("new string is "+ newStr);
00858 if(ans.compare(newStr)==0) {
00859 correctCounting++;
00860 }else{
00861 incorrectCounting++ ;
00862 int n1 = charmap[newStr.substr(0,1)];
00863 int n2 = charmap[newStr.substr(newStr.size()-1,1)];
00864 missCounting += abs(n1-tonesVector.at(0)) + abs(n2-tonesVector.at(1)) ;
00865 }
00866
00867 }
00868 cr++;
00869 }
00870 d->pushEvent("correct spatial memory: " +stringify(correctSpatialMemory));
00871 d->pushEvent("incorrect spatial memory: " +stringify(incorrectSpatialMemory));
00872 d->pushEvent("correct counting: " +stringify(correctCounting));
00873 d->pushEvent("incorrect counting: " +stringify(incorrectCounting));
00874 d->pushEvent("misscounting: "+stringify(missCounting));
00875 d->displayText("Experiment complete. Thank you!");
00876 d->waitForMouseClick();
00877
00878
00879 manager.stop();
00880
00881
00882
00883 return 0;
00884 }
00885
00886 #endif // INVT_HAVE_LIBSDL_IMAGE
00887