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-Orientation");
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 dir , int ma=30 ,int Ma=120){
00557
00558 int w = d->getWidth();
00559 int h = d->getHeight();
00560 int neg = rand()%(Ma-ma) +ma ;
00561 int pos = rand()%(Ma-ma) +ma ;
00562
00563 if(dir==0) {
00564 d->displayRedDotFixation(w/2+pos,h/2);
00565 d->waitFrames(onsetTime);
00566 d->clearScreen();
00567 d->waitFrames(isd);
00568 d->displayRedDotFixation(w/2-neg,h/2);
00569 d->waitFrames(onsetTime);
00570 d->clearScreen();
00571 }
00572 if(dir==1) {
00573 d->displayRedDotFixation(w/2,h/2+pos);
00574 d->waitFrames(onsetTime);
00575 d->clearScreen();
00576 d->waitFrames(isd);
00577 d->displayRedDotFixation(w/2,h/2-neg);
00578 d->waitFrames(onsetTime);
00579 d->clearScreen();
00580 }
00581 vector<int> locations;
00582 locations.push_back(neg);
00583 locations.push_back(pos);
00584 return locations ;
00585 }
00586
00587 int spatial_memory_retrival(vector<int> dotsVector,int dir ,float cr = 0.5 ){
00588
00589 int w = d->getWidth();
00590 int h = d->getHeight();
00591 int change = rand()%2;
00592 int neg = dotsVector.at(0); int pos = dotsVector.at(1);
00593 switch( change ){
00594 case 0 : d->pushEvent("same target");break;
00595 case 1 : d->pushEvent("target changed");break;
00596 }
00597 if(change == 1){
00598 int chDir = rand()%2;
00599 int c=0;
00600 switch(chDir){
00601 case 0: c =((rand()%2 -0.5)/0.5 ); neg = neg + c* cr*neg ; break ;
00602 case 1: c =((rand()%2 -0.5)/0.5 ); pos = pos + c* cr*pos ; break ;
00603 }
00604 }
00605
00606 d->pushEvent("for retrieval dots showed at negative side :"+ stringify(neg)+" positive side:" + stringify(pos));
00607 if(dir == 0){
00608 d->displayRedDotFixation(w/2+pos,h/2);
00609 d->displayRedDotFixation(w/2-neg,h/2);
00610 }
00611 if(dir == 1){
00612 d->displayRedDotFixation(w/2,h/2+pos);
00613 d->displayRedDotFixation(w/2,h/2-neg);
00614 }
00615 d->waitFrames(30);
00616 d->clearScreen();
00617 string ans = getDigitSequenceFromSubject("yn-",1);
00618 int res = 0 ;
00619 if(change==0 && ans.compare("y")==0) res=1;
00620 if(change==1 && ans.compare("n")==0) res=1;
00621 return res ;
00622 }
00623
00624 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 ){
00625 int t1c = 0 ;
00626 int t2c = 0 ;
00627 vector<int> wFrames;
00628 vector<int> toneSequence ;
00629 vector<int> retVector ;
00630 map<int,string> strMap;
00631
00632 int flag=0;
00633 float milisum=0;
00634 do{
00635 int rtmp = rand()%(max_tone_wait - min_tone_wait) + min_tone_wait;
00636 milisum += rtmp*33.33 + 240;
00637 if(milisum > counter_length*33.33) {
00638 milisum = milisum -rtmp*33.33 - 240;
00639 flag=1;
00640 }else{
00641 wFrames.push_back(rtmp);
00642 toneSequence.push_back(rand()%2);
00643 }
00644 }while(flag==0);
00645 int lagFrames = (int)((counter_length - milisum)/33.33);
00646
00647 for(uint i = 0 ; i < wFrames.size() ; i++){
00648 d->pushEvent("will wait for "+stringify(wFrames[i]));
00649 d->waitFrames(wFrames[i]);
00650 if(toneSequence[i]==0){
00651 d->pushEvent("tone1 playing");
00652 t1c++;
00653 if(Mix_PlayMusic(tone1,0)==-1){return retVector;}
00654 while(Mix_PlayingMusic()==1){} ;
00655 }else{
00656 d->pushEvent("tone2 playing");
00657 t2c++ ;
00658 if(Mix_PlayMusic(tone2,0)==-1){return retVector;}
00659 while(Mix_PlayingMusic()==1){} ;
00660 }
00661 }
00662 d->waitFrames(lagFrames);
00663 retVector.push_back(t1c);
00664 retVector.push_back(t2c);
00665 d->clearScreen();
00666 d->displayFixation();
00667 return retVector ;
00668
00669 }
00670
00671
00672
00673 std::string getUsageComment(){
00674
00675 string com = string("\nlist of arguments : \n");
00676
00677 com += "\nlogfile=[logfilename.psy] {default = psycho-sm-or.psy}\n" ;
00678 com += "\nmemo=[a_string_without_white_space]\n";
00679 com += "\nstring-size=[>0](the size of counter string){default=4} \n";
00680 com += "\nsubject=[subject_name] \n" ;
00681 com += "\nnum-of-trials=[>1] (number of trials ) {default=10}\n";
00682 com += "\nalphabet=[a string of characters](a string of characters){default=abcdefghijklmnopqrstuvwxyz}\n";
00683 com += "\nmode=[1,2,3](1 for spatial memory task 2 for single counter task, 2 for concurrent task){default=1}\n";
00684 com += "\nsingle-dot-onset=[>1](number of frames that the single dot should be presented){default=16}\n";
00685 com += "\ndots_ISI=[>1](number of frames between dots presentations){default=16}\n";
00686 com += "\ndots_radius=[>1](the radius for circle of dots in pixel){default=100}\n";
00687 com += "\ndots_min_angle=[>0](minimum angle between dots on the circle){default=45}\n";
00688 com += "\ndots_max_angle=[>0] (maximum angle between dots on the circle){default=90}\n";
00689 com += "\nspatial-delay=[>0](number of frames for spatial memory task ){default=180}\n";
00690 com += "\n spatial-counter-ISI=[>1](numer of frames between last dot presentation and start of counter task){default=16}\n";
00691 com += "\n counter-length=[>1](total lenght of counter experiment in frames){default=300}\n";
00692 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";
00693 com += "\n spatial-query-length=[>1](the total length for showing the spatial memory test in number of frames){default=60}\n";
00694 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";
00695 com += "\n counter-query-length=[>1](number of frames for presenting the counter query){default=60}\n";
00696 com += "\n cue-onset-frames=[>1](){default=3}\n";;
00697 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00698 com += "\ntone1=[a valid file name](name of wav file without extension for tone 1){default=sin}\n";
00699 com += "\ntone2=[a valid file name](name of wav file without extension for tone 2){default=square}\n";
00700 com += "\ncue-file=[a valid file name](name of a wav file without extension for the audio cue){default=cue1}\n";
00701 com += "\nmin-tone-wait=[>1](minimum number of frames waiting on each tone){default=60}\n";
00702 com += "\nmax-tone-wait=[>1](maximum number of frames waiting on each tone){default=90}\n";
00703 com += "\ndot-shift=[>1](amount of shift in dots position in pixel)[default=16]\n";
00704 return com ;
00705 }
00706
00707 extern "C" int main(const int argc, char** argv)
00708 {
00709
00710 MYLOGVERB = LOG_INFO;
00711
00712 argMap["experiment"]="spatial-memory-test";
00713 argMap["logfile"]="psycho-sm.psy" ;
00714 argMap["string-size"]="3" ;
00715 argMap["num-of-trials"]="10";
00716 argMap["subject"]="" ;
00717 argMap["memo"]="" ;
00718 argMap["single-dot-onset"]="16" ;
00719 argMap["dots-ISI"]="16";
00720 argMap["spatial-delay"]="180";
00721 argMap["spatial-counter-ISI"]="16";
00722 argMap["counter-length"]="300";
00723 argMap["counter-spatial-query-ISI"]="16";
00724 argMap["spatial-query-length"]="60";
00725 argMap["spatial-query-counter-query-ISI"]="30";
00726 argMap["counter-query-length"]="60";
00727 argMap["alphabet"]="0123456789";
00728 argMap["mode"]="1" ;
00729 argMap["cue-onset-frames"] = "3" ;
00730 argMap["sound-dir"]="..";
00731 argMap["tone1"]="sine";
00732 argMap["tone2"]="square";
00733 argMap["cue-file"]="cue1";
00734 argMap["min-tone-wait"]="50";
00735 argMap["max-tone-wait"]="80";
00736 argMap["dots_min_radius"]="12";
00737 argMap["dots_max_radius"]="96";
00738 argMap["dot-shift"] = "0.75";
00739 manager.addSubComponent(d);
00740 nub::soft_ref<EventLog> el(new EventLog(manager));
00741 manager.addSubComponent(el);
00742 d->setEventLog(el);
00743 nub::soft_ref<EyeTrackerConfigurator>
00744 etc(new EyeTrackerConfigurator(manager));
00745 manager.addSubComponent(etc);
00746
00747 if (manager.parseCommandLine(argc, argv,
00748 "at least one argument needed", 1, -1)==false){
00749 cout<<getUsageComment()<<endl;
00750 return(1);
00751 }
00752
00753 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00754 addArgument(manager.getExtraArg(i),std::string("=")) ;
00755 }
00756
00757 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00758
00759
00760
00761
00762
00763
00764
00765 manager.start();
00766 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00767
00768 d->clearScreen();
00769 d->displayISCANcalib();
00770 d->waitForMouseClick();
00771 d->displayText("Here the experiment starts! click to start!");
00772 d->waitForMouseClick();
00773 d->clearScreen();
00774
00775
00776 string masterString=argMap["alphabet"];
00777
00778
00779 int numOfTests = atoi(argMap["num-of-trials"].c_str()) ;
00780 int stringSize = atoi(argMap["string-size"].c_str());
00781 int dots_ISI = atoi(argMap["dots-ISI"].c_str()) ;
00782 int dot_onset = atoi(argMap["single-dot-onset"].c_str());
00783 int dots_min_radius = atoi(argMap["dots_min_radius"].c_str());
00784 int dots_max_radius = atoi(argMap["dots_max_radius"].c_str());
00785 int mode = atoi(argMap["mode"].c_str());
00786 int counter_length = atoi(argMap["counter-length"].c_str());
00787 int min_tone_wait = atoi(argMap["min-tone-wait"].c_str());
00788 int max_tone_wait = atoi(argMap["max-tone-wait"].c_str());
00789 float dot_max_change = atof(argMap["dot-shift"].c_str());
00790 vector<int> orVector;
00791 for( int i = 0 ; i< numOfTests/2 ; i++ ){
00792 orVector.push_back(0);
00793 }
00794 for( int i =numOfTests/2; i<numOfTests ; i++){
00795 orVector.push_back(1);
00796 }
00797 scramble(orVector);
00798
00799
00800
00801 d->clearScreen();
00802
00803 cout<< stringify(d->getWidth())<<" x "<<stringify(d->getHeight())<<endl;
00804 Mix_Music* cueMusic = NULL;
00805 Mix_Music* tone1 = NULL;
00806 Mix_Music* tone2 = NULL;
00807 map<int,Mix_Music*> audio_map ;
00808 map<string,int> charmap ;
00809 map<int,string> charinvmap ;
00810
00811 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00812 LINFO( "did not open the mix-audio") ;
00813 return -1 ;
00814 }
00815
00816 for(uint i = 0; i < masterString.size() ; i++){
00817 string str = argMap["sound-dir"]+"/"+masterString.substr(i,1)+".wav";
00818 audio_map[i]=Mix_LoadMUS(str.c_str());
00819 charmap[masterString.substr(i,1)]=i;
00820 charinvmap[i]=masterString.substr(i,1) ;
00821 }
00822
00823 for( uint i=10;i<100 ;i++ ){
00824 charmap[stringify(i)]=i;
00825 charinvmap[i]=stringify(i);
00826 }
00827
00828 if(argMap["cue-type"].compare("a")==0){
00829 string str = argMap["sound-dir"]+"/"+argMap["cue-file"]+".wav" ;
00830 cueMusic = Mix_LoadMUS(str.c_str());
00831 }
00832
00833 string tmpstr = argMap["sound-dir"]+"/"+argMap["tone1"]+".wav";
00834 tone1 = Mix_LoadMUS(tmpstr.c_str());
00835 tmpstr = argMap["sound-dir"]+"/"+argMap["tone2"]+".wav";
00836 tone2 = Mix_LoadMUS(tmpstr.c_str());
00837
00838 int cr = numOfTests ;
00839 d->showCursor(true);
00840 d->displayText("click one of the mouse buttons to start!");
00841 d->waitForMouseClick() ;
00842 d->showCursor(false);
00843
00844 int correctHSpatialMemory=0;
00845 int correctVSpatialMemory=0;
00846 int incorrectHSpatialMemory=0;
00847 int incorrectVSpatialMemory=0;
00848 int correctCounting=0;
00849 int incorrectCounting=0;
00850 int missCounting=0;
00851 cr=0;
00852 while( cr < numOfTests ){
00853 string inStr = getARandomString(stringSize,"34567");
00854 d->showCursor(false);
00855 d->clearScreen() ;
00856 d->pushEvent("**************************************") ;
00857 d->pushEvent("initial string :" + inStr);
00858 for(uint i = 0 ; i < inStr.size(); i++){
00859 d->pushEvent("playing character "+inStr.substr(i,1));
00860 if(Mix_PlayMusic(audio_map[charmap[inStr.substr(i,1)]],0)==-1){return 1;}
00861 while(Mix_PlayingMusic()==1){} ;
00862 d->pushEvent("ended playing character "+inStr.substr(i,1));
00863 }
00864 d->waitFrames(60);
00865 d->displayFixation();
00866 d->waitFrames(10);
00867 d->clearScreen() ;
00868 d->pushEvent("presentation orientation: " + stringify(orVector.at(cr)));
00869 vector<int> dotsVector = spatial_memory_task(dot_onset,dots_ISI,orVector.at(cr),dots_min_radius,dots_max_radius);
00870 d->pushEvent("dots showed at negative:"+ stringify(dotsVector.at(0))+" positive:" + stringify(dotsVector.at(1)));
00871 d->waitFrames(10);
00872 d->displayFixation();
00873 vector<int> tonesVector = executive_memory_task( tone1 , tone2 , inStr, counter_length, min_tone_wait, max_tone_wait );
00874 string newStr ;
00875 if (stringSize == 2)
00876 newStr = charinvmap[charmap[inStr.substr(0,1)]+tonesVector.at(0)]+charinvmap[charmap[inStr.substr(inStr.size()-1,1)]+tonesVector.at(1)];
00877 if (stringSize>2)
00878 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)];
00879 if(mode==1 || mode==3){
00880 int spMemAns = spatial_memory_retrival(dotsVector,orVector.at(cr),dot_max_change);
00881 if(orVector.at(cr)==0){
00882 if (spMemAns ==1){
00883 d->pushEvent("correct horizontal spatial memory recall");
00884 correctHSpatialMemory++;
00885 }else{
00886 d->pushEvent("incorrect horizontal spatial memory recall");
00887 incorrectHSpatialMemory++;
00888 }
00889 }else{
00890 if (spMemAns ==1){
00891 d->pushEvent("correct horizontal spatial memory recall");
00892 correctVSpatialMemory++;
00893 }else{
00894 d->pushEvent("incorrect horizontal spatial memory recall");
00895 incorrectVSpatialMemory++;
00896 }
00897
00898 }
00899 }
00900
00901
00902 if(mode ==1){
00903
00904 string ans1 = getDigitSequenceFromSubject(masterString,1,"first digit");
00905 d->pushEvent("subject keyed:" + ans1 + " for first digit");
00906 string ans2 = getDigitSequenceFromSubject(masterString,1,"second digit");
00907 d->pushEvent("subject keyed:" + ans2 + " for second digit");
00908
00909 if(ans1.compare(inStr.substr(0,1))==0 && ans2.compare(inStr.substr(inStr.size()-1,1))==0 ) {
00910 correctCounting++;
00911 }else{
00912 incorrectCounting++ ;
00913 }
00914
00915 }
00916
00917 if(mode ==2 || mode==3){
00918 int sineCounter = tonesVector.at(0)+atoi(inStr.substr(0,1).c_str());
00919 int squareCounter = tonesVector.at(1)+atoi(inStr.substr(inStr.size()-1,1).c_str());
00920 d->pushEvent("sine signal counter is :"+stringify(sineCounter));
00921 d->pushEvent("square signal counter is :"+stringify(squareCounter));
00922 string ans1 = getDigitSequenceFromSubject(masterString,2,"soft tone counter");
00923 d->pushEvent("subject keyed:" + ans1 + " for sine counter");
00924 string ans2 = getDigitSequenceFromSubject(masterString,2,"rough tone counter");
00925 d->pushEvent("subject keyed:" + ans2 + " for square counter");
00926 d->pushEvent("trial misscounting: " + stringify(abs(atoi(ans1.c_str()) - sineCounter) + abs(atoi(ans2.c_str()) - squareCounter)));
00927 missCounting += abs(atoi(ans1.c_str()) - sineCounter) + abs(atoi(ans2.c_str()) - squareCounter);
00928
00929 }
00930 cr++;
00931 }
00932 d->pushEvent("correct horizontal spatial memory: " +stringify(correctHSpatialMemory));
00933 d->pushEvent("incorrect horizontal spatial memory: " +stringify(incorrectHSpatialMemory));
00934
00935 d->pushEvent("correct vertical spatial memory: " +stringify(correctVSpatialMemory));
00936 d->pushEvent("incorrect vertical spatial memory: " +stringify(incorrectVSpatialMemory));
00937 d->pushEvent("correct counting: " +stringify(correctCounting));
00938 d->pushEvent("incorrect counting: " +stringify(incorrectCounting));
00939 d->pushEvent("total misscounting: "+stringify(missCounting));
00940 d->displayText("Experiment complete. Thank you!");
00941 d->waitForMouseClick();
00942
00943
00944 manager.stop();
00945
00946
00947
00948 return 0;
00949 }
00950
00951 #endif // INVT_HAVE_LIBSDL_IMAGE
00952