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