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 <stdio.h>
00059 #include <stdlib.h>
00060 #include <sstream>
00061 #include <time.h>
00062 #include "Image/DrawOps.H"
00063 #include "GameBoard/resize.h"
00064 #include <iostream>
00065 #include <fstream>
00066 #include <set>
00067 #include <algorithm>
00068 #include <ctime>
00069 #include "Devices/SimpleMotor.H"
00070 #include <SDL/SDL_mixer.h>
00071
00072 #ifndef INVT_HAVE_LIBSDL_IMAGE
00073 #include <cstdio>
00074 int main()
00075 {
00076 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00077 return 1;
00078 }
00079
00080 #else
00081
00082
00083
00084 using namespace std;
00085
00086
00087
00088 ModelManager manager("Psycho-Concurrent-Digit");
00089 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00090 nub::soft_ref<SimpleMotor> motor(new SimpleMotor(manager));
00091 map<uint,uint> testMap ;
00092 map<string,string> argMap ;
00093 Mix_Chunk *audio_chunk = NULL;
00094
00095
00096
00097
00098 template <class T> std::string stringify(T i)
00099 {
00100 ostringstream o ;
00101 o << i ;
00102 return o.str();
00103 }
00104
00105
00106
00107
00108 bool itIsInThere(int x , vector<int> bag){
00109 for( uint i=0 ; i < bag.size(); i++ ){
00110 if(x == bag[i]) return true ;
00111 }
00112 return false ;
00113 }
00114
00115
00116 double getAvarage(vector<long> v){
00117 double f = 0.0 ;
00118 for( uint i = 0 ; i < v.size() ; i++ ){
00119 f += v[i] ;
00120 }
00121 if (v.size()!=0) return f/v.size() ;
00122 return -1 ;
00123 }
00124
00125 double getVariance(vector<long> v){
00126 double m = getAvarage(v);
00127 double var = 0.0 ;
00128 for( uint i = 0 ; i < v.size(); i++ ){
00129 var += (v[i]-m)*(v[i]-m) ;
00130 }
00131 if (v.size()!=0) return var/v.size() ;
00132 return -1 ;
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 string ascSort(string st)
00144 {
00145 string res = "" ;
00146 vector<string> v = vector<string>();
00147 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00148
00149 std::sort(v.begin(), v.end());
00150
00151 for ( uint i = 0 ; i < v.size() ; i++ ){
00152 res += v[i] ;
00153 }
00154 return res;
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 string desSort(string st)
00164 {
00165 string res = "" ;
00166 vector<string> v = vector<string>();
00167 for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00168 std::sort(v.begin(), v.end());
00169 std::reverse(v.begin(), v.end());
00170 for ( uint i = 0 ; i < v.size() ; i++ ){
00171 res += v[i] ;
00172 }
00173 return res;
00174 }
00175
00176
00177
00178
00179
00180
00181
00182 int mydist(string str , string sorted){
00183 size_t found;
00184 int m = 0 ;
00185 for(uint i = 2 ; i <= sorted.size() ; i++ ){
00186 for(uint j = 0 ; j <= sorted.size()-i ; j++ ) {
00187 found = str.find(sorted.substr(j,i));
00188 if (found!=string::npos) m += i ;
00189 }
00190 }
00191 return m ;
00192 }
00193
00194
00195
00196
00197
00198
00199 int getDisMetric(string st){
00200 int m = 0 ;
00201 size_t found;
00202 string asString = ascSort(st) ;
00203 for(uint i = 0 ; i < st.size() ; i++ ){
00204 found = asString.find(st.substr(i,1));
00205 m += abs((int)i-int(found)) ;
00206 }
00207
00208 return m- 2*mydist(st,asString) ;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218 string getARandomString(uint l, string alphabet="0123456789" , int thresh=0){
00219
00220 string test = string("") ;
00221 string retString ;
00222 int maxDist = -1000000;
00223 int it = 0 ;
00224 int d = 0 ;
00225 do{
00226 test = "" ;
00227 string tp = string("") ;
00228 vector<int> pickedones = vector<int>() ;
00229 for(uint i = 0 ; i < l ; i++){
00230 int nd;
00231 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00232 pickedones.push_back(nd);
00233 tp = alphabet.substr(nd,1) ;
00234 test += tp ;
00235 }
00236 it++ ;
00237 d = getDisMetric(test);
00238 maxDist=max(maxDist,d) ;
00239 if (d==maxDist) retString = test ;
00240
00241 }while( maxDist<thresh && it < 1000000);
00242
00243 return retString ;
00244 }
00245
00246
00247
00248
00249
00250 string digitMemorizationTask(uint l, string alphabet="0123456789" , int displayFrame = 10 ){
00251 d->clearScreen() ;
00252 vector<int> pickedones = vector<int>() ;
00253 string test = string("") ;
00254 string tp = string("") ;
00255 for(uint i = 0 ; i < l ; i++){
00256 int nd;
00257 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00258 pickedones.push_back(nd);
00259 tp = alphabet.substr(nd,1) ;
00260 test += tp ;
00261 }
00262 d->displayText(test,true,0) ;
00263 d->waitFrames(displayFrame) ;
00264 d->clearScreen() ;
00265 return test ;
00266 }
00267
00268
00269
00270
00271
00272 void scramble(vector<string>& v){
00273 vector<string> tv = vector<string>() ;
00274 while(v.size()>0){
00275 tv.push_back(v[0]);
00276 v.erase(v.begin());
00277 }
00278 int i = 0 ;
00279 while(tv.size()>0){
00280 i = rand()%tv.size() ;
00281 v.push_back(tv[i]);
00282 tv.erase(tv.begin()+i);
00283 }
00284 }
00285
00286
00287
00288
00289
00290 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){
00291 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00292 textIm.clear(bgcolor);
00293 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00294 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00295 Uint32 bc = d->getUint32color(bordercolor);
00296 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00297 SDL_Surface* blank =getABlankSurface(size.i , size.j);
00298 SDL_Rect clip;
00299 clip.x = 0 ;
00300 clip.y = 0 ;
00301 clip.w = size.i ;
00302 clip.h = size.j ;
00303 apply_surface(0,0,*surf,*blank,clip);
00304 dumpSurface(surf) ;
00305 return blank ;
00306 }
00307
00308
00309
00310
00311
00312
00313 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00314 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00315 SDL_Rect clip;
00316 clip.x=0;
00317 clip.y=0;
00318 int numofrows = alphabet.size()/3 +1;
00319 if(alphabet.size()%3 != 0 ) numofrows++ ;
00320 int numofcolumns = 3 ;
00321 clip.w= pad->w / numofcolumns ;
00322 clip.h = pad->h / numofrows ;
00323
00324
00325 for( int i = 0 ; i < numofrows*3 ; i++){
00326 SDL_Surface* but ;
00327 if((uint)i < alphabet.size()){
00328 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);
00329 }else{
00330 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);
00331 }
00332
00333 SDL_Rect cl ;
00334 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00335 cl.w = clip.w ;
00336 cl.h = clip.h ;
00337 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00338 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00339 dumpSurface(but);
00340 }
00341 SDL_Rect cl1 ;
00342 cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00343 cl1.w = clip.w ;
00344 cl1.h = clip.h ;
00345 buttmap["!"] = cl1 ;
00346 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);
00347 apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00348 dumpSurface(but);
00349 SDL_Rect cl2 ;
00350 cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00351 cl2.w = clip.w ;
00352 cl2.h = clip.h ;
00353 buttmap[" "] = cl2 ;
00354 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);
00355 apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00356 dumpSurface(but);
00357 SDL_Rect cl3 ;
00358 cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00359 cl3.w = clip.w ;
00360 cl3.h = clip.h ;
00361 buttmap["*"] = cl3 ;
00362 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);
00363 apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00364 dumpSurface(but);
00365 return pad ;
00366 }
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00377 int quit = 0 ;
00378 string s ;
00379 SDL_Event event ;
00380 while( quit!=2 ){
00381 while( SDL_PollEvent( &event ) ) {
00382 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){
00383 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00384 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) {
00385 quit = 2 ;
00386 s = it->first ;
00387 break;
00388 }
00389
00390 }
00391 }
00392
00393 }
00394 }
00395 return s ;
00396
00397 }
00398
00399
00400
00401
00402
00403
00404
00405 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00406 d->showCursor(true) ;
00407
00408 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00409
00410 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00411
00412 SDL_Rect offset ;
00413 offset.x = (d->getWidth() - keypad->w) /2;
00414 offset.y = (d-> getHeight() - keypad->h) /2;
00415
00416 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00417
00418 string p = string("") ;
00419
00420 string tp = string("");
00421
00422 while( tp.compare("*")!=0 ){
00423
00424 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) ;
00425 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00426 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00427
00428 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00429 dumpSurface(dp) ;
00430 if(tp.compare("!")==0 && p.size()>=0 ) {
00431 if (p.size()>0) p = p.substr(0,p.size()-1) ;
00432 }else{
00433 if(p.size() < maxl && tp.compare("*")!=0) {
00434 p +=tp ;
00435 }
00436
00437 }
00438
00439 }
00440 buttmap = 0 ;
00441 dumpSurface(keypad) ;
00442 d->clearScreen() ;
00443 return p ;
00444
00445 }
00446
00447
00448 void showMask(int frames, string alphabet="0123456789"){
00449 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00450 PixRGB<byte> bgcolor = PixRGB<byte>(128,128,128);
00451 PixRGB<byte> txtcolor = PixRGB<byte>(0,0,0);
00452 textIm.clear(bgcolor);
00453 for(int i = 0 ; i < 200 ; i++)
00454 writeText(textIm, Point2D<int>((int)random()%(d->getWidth()),(int)random()%(d->getHeight())),alphabet.substr(random()%(int)alphabet.size(),1).c_str(),txtcolor,bgcolor);
00455 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00456 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00457 d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00458 d->waitFrames(frames) ;
00459 d->clearScreen();
00460 dumpSurface(surf) ;
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470 bool isAnswerCorrect(string test , string answer , int mode){
00471
00472 if(mode == 0 && answer.compare(test)==0) return true ;
00473
00474 if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00475
00476 if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00477
00478 return false;
00479 }
00480
00481
00482
00483 int addArgument(const string st,const string delim="="){
00484 int i = st.find(delim) ;
00485 argMap[st.substr(0,i)] = st.substr(i+1);
00486
00487 return 0 ;
00488 }
00489
00490 std::string getArgumentValue(string arg){
00491 return argMap[arg] ;
00492 }
00493
00494 std::string getUsageComment(){
00495
00496 string com = string("\nlist of arguments : \n");
00497 com += "\nlogfile=[logfilename.psy] {default =psycho-wm-m.psy}\n" ;
00498 com += "\nmemo=[a_string_without_white_space]\n";
00499 com += "\nstring-size=[>0](the size of string){default=5} \n";
00500 com += "\nsubject=[subject_name] \n" ;
00501 com += "\ntest-rounds=[>1] (number of tests ) {default=10}\n";
00502 com += "\ndigit-onset=[>1] (number of frames that the string will remain onset ){default=10}\n";
00503 com += "\nalphabet=[a string of characters](a string of characters){default=0123456789}\n";
00504 com += "\nmetric-thresholdt=[>-30 for string of lenght of 5](a string of characters){default=10}\n";
00505 com += "\nmaintain-prb=[a number between 0 to 1], probability of challenging the subject with a memorization task, default=0.2\n" ;
00506 com += "\nmin-reaction-time=[>0](minimum value for avarage reaction time in microsecond in order to consider a trial valid){default=1000000}\n" ;
00507 com += "\nmax-miss=[>0](maximum misses in a trial in order to be considered as a valid one){default=0}";
00508 com += "\nmax-false-click=[>0](maximum false clicks in a trial in order to be considered as a valid one){default=0}";
00509 com += "\ninterrupt-time-range=[x-y](this defines a range of uniform radom distribution by which the perceptual interruption happens){default=500000-5000000}\n" ;
00510 com += "\ncue-wait-frames=[<0](number of frames to show the cue){default=0}\n";
00511 com += "\ncue-onset-frames=[<0](number of frames to show the cue onset){default=3}\n";
00512 com += "\nmask=[y/n](whether present a mask after presentation, n for no, y for yes ){default=n}\n" ;
00513 com += "\nmask-onset-frames=[<0](number of frames that mask will be onset){default=0}\n";
00514 com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00515 com += "\audio-file=[white noise file]{default=audio.wav}\n";
00516 com += "\npuase-frames=[number of frames for stopping the the audio playback]{default=5}\n";
00517 return com ;
00518 }
00519
00520 int myCheckForMouseClick()
00521 {
00522 SDL_Event event;
00523
00524 while(SDL_PollEvent(&event))
00525 {
00526 if (event.type == SDL_MOUSEBUTTONDOWN)
00527 {
00528 if(event.button.button == SDL_BUTTON_LEFT) {
00529 return 1 ;
00530 }
00531 if(event.button.button == SDL_BUTTON_RIGHT) {
00532 return 2 ;
00533 }
00534
00535 }
00536
00537 }
00538
00539
00540 return -1;
00541 }
00542
00543
00544 int getClick(){
00545
00546 SDL_Event event;
00547 bool report = false ;
00548 int i = 0;
00549 do {
00550 do { SDL_WaitEvent(&event); } while (event.type != SDL_MOUSEBUTTONDOWN);
00551 if (event.button.button == SDL_BUTTON_LEFT) {
00552 i = 0 ;
00553 report = true ;
00554 }
00555 if (event.button.button == SDL_BUTTON_RIGHT) {
00556 i = 1 ;
00557 report = true ;
00558 }
00559
00560 }while(!report) ;
00561
00562 return i ;
00563 }
00564
00565 int getAllKindOfClick(){
00566
00567 SDL_Event event;
00568 bool report = false ;
00569 int i = 0;
00570 do {
00571 do { SDL_WaitEvent(&event); } while (event.type != SDL_MOUSEBUTTONDOWN);
00572 long st = d->getTimerValue();
00573 long et = st ;
00574
00575 if (event.button.button == SDL_BUTTON_LEFT) {
00576 i = 0 ;
00577 report = true ;
00578 while( et-st < 300000){
00579 et = d->getTimerValue() ;
00580 if(myCheckForMouseClick()==1) return 2 ;
00581 }
00582 }
00583 if (event.button.button == SDL_BUTTON_RIGHT) {
00584 i = 1 ;
00585 report = true ;
00586 }
00587
00588 }while(!report) ;
00589
00590 return i ;
00591
00592 }
00593
00594 int getNext(int i){
00595
00596 int r = 1 ;
00597 if(i == 0 || i == 2) return 1 ;
00598 if(i==1) return 0;
00599 return r ;
00600 }
00601
00602 extern "C" int main(const int argc, char** argv)
00603 {
00604
00605 MYLOGVERB = LOG_INFO;
00606
00607 argMap["experiment"]="sorting_strings_in_working_memory-with-somatosensory-task";
00608 argMap["logfile"]="psycho-wm-m.psy" ;
00609 argMap["string-size"]="5" ;
00610 argMap["test-rounds"]="10";
00611 argMap["subject"]="" ;
00612 argMap["memo"]="" ;
00613 argMap["digit-onset"]="10" ;
00614 argMap["alphabet"]="0123456789";
00615 argMap["metric-threshold"]="10" ;
00616 argMap["maintain-prb"]="0.2" ;
00617 argMap["min-reaction-time"]="1000000" ;
00618 argMap["max-miss"]="0" ;
00619 argMap["interrupt-time-range"]= "500000-5000000";
00620 argMap["cue-wait-frames"]="0" ;
00621 argMap["mask"]="n" ;
00622 argMap["mask-onset-frames"]="0";
00623 argMap["cue-onset-frames"] = "3" ;
00624 argMap["sound-dir"]="..";
00625 argMap["audio-file"]="audio.wav";
00626 argMap["pause-frames"]="5" ;
00627 argMap["max-false-click"]="0";
00628 manager.addSubComponent(d);
00629 manager.addSubComponent(motor) ;
00630 nub::soft_ref<EventLog> el(new EventLog(manager));
00631 manager.addSubComponent(el);
00632 d->setEventLog(el);
00633
00634
00635
00636 if (manager.parseCommandLine(argc, argv,
00637 "at least one argument needed", 1, -1)==false){
00638 cout<<getUsageComment()<<endl;
00639 return(1);
00640 }
00641
00642 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00643 addArgument(manager.getExtraArg(i),std::string("=")) ;
00644 }
00645
00646 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00647
00648 if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00649 LINFO( "did not open the mix-audio") ;
00650 return -1 ;
00651 }
00652 string noisestr = argMap["sound-dir"] + "/" + argMap["audio-file"];
00653 audio_chunk = Mix_LoadWAV(noisestr.c_str());
00654 if( audio_chunk == NULL )
00655 {
00656 LINFO("did not find the indicated wav files!");
00657 return -1;
00658 }
00659
00660
00661
00662 manager.start();
00663 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00664 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00665
00666
00667 d->clearScreen();
00668 d->displayISCANcalib();
00669 d->waitForMouseClick();
00670 d->displayText("Here the experiment starts! click to start!");
00671 d->waitForMouseClick();
00672 d->clearScreen();
00673
00674
00675 int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00676 int stringSize = atoi(argMap["string-size"].c_str());
00677 int meticThreshold = atoi(argMap["metric-threshold"].c_str()) ;
00678 int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00679 float memPrb = atof(argMap["maintain-prb"].c_str()) ;
00680 int max_miss = atoi(argMap["max-miss"].c_str());
00681 int max_wrong = atoi(argMap["max-false-click"].c_str()) ;
00682 int in = argMap["interrupt-time-range"].find("-") ;
00683 long iub = atol(argMap["interrupt-time-range"].substr(in+1).c_str());
00684 long ilb = atol(argMap["interrupt-time-range"].substr(0,in).c_str()) ;
00685 long min_reaction_time = atol(argMap["min-reaction-time"].c_str()) ;
00686 int cue_onset_frames = atoi(argMap["cue-onset-frames"].c_str()) ;
00687 int cue_wait_frames = atoi(argMap["cue-wait-frames"].c_str()) ;
00688 int mask_onset_frames = atoi(argMap["mask-onset-frames"].c_str()) ;
00689 int pause_frames = atoi(argMap["pause-frames"].c_str());
00690 vector<int> speedVector;
00691 speedVector.push_back(110) ;
00692 speedVector.push_back(-110) ;
00693 speedVector.push_back(150) ;
00694 Mix_PlayChannel( -1, audio_chunk , 500 ) ;
00695 int cr = 0 ;
00696 int fm =0 ;
00697 int sm = 0 ;
00698 int ssfr=0 ;
00699 int fssr=0 ;
00700 int sssr=0 ;
00701 int fsfr=0 ;
00702 vector<long> correctAnswersTiming;
00703 vector<long> incorrectAnswersTiming;
00704 vector<long> allTiming ;
00705 while( cr <numOfTests ){
00706 float mP = (float) rand()/RAND_MAX ;
00707 if(mP > memPrb){
00708
00709 d->pushEvent("**************************************") ;
00710 d->showCursor(true);
00711 d->displayText("click one of the mouse buttons to start!");
00712 d->waitForMouseClick() ;
00713 d->showCursor(false) ;
00714 string testString ;
00715 vector<long> reactionTimes ;
00716 testString = getARandomString(stringSize, argMap["alphabet"] , meticThreshold);
00717 d->clearScreen() ;
00718 d->displayFixationBlink();
00719 d->displayText(testString,true,0) ;
00720 d->waitFrames(onsetDel) ;
00721 d->clearScreen() ;
00722 if(argMap["mask"].compare("y")==0) showMask(mask_onset_frames,argMap["alphabet"]);
00723 if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00724 d->displayRedDotFixation();
00725 d->waitFrames(cue_onset_frames);
00726 int cs = 0 ;
00727
00728 motor->setMotor(speedVector[cs]) ;
00729 long st = d->getTimerValue() ;
00730 d->clearScreen() ;
00731 d->pushEvent("manipulation starts");
00732 d->pushEvent("the sequence for manipulation is : "+testString) ;
00733 long tst =0 ;
00734 long tet =0 ;
00735 long dst = 0 ;
00736 long det = 0 ;
00737 long dl = 0 ;
00738 dl = ilb+ random() % (iub-ilb);
00739 dst = d->getTimerValue() ;
00740 det = dst ;
00741 int missed = 0 ;
00742 bool exitFlag = false ;
00743 bool clickFlag = false ;
00744 int ms = -1 ;
00745 int wrongclick = 0 ;
00746 while( !exitFlag ){
00747
00748 if (det - dst > dl ){
00749 cs = getNext(cs) ;
00750 motor->setMotor(0) ;
00751 d->waitFrames(pause_frames);
00752 motor->setMotor(speedVector[cs]) ;
00753 tst = d->getTimerValue() ;
00754 det=tst ;
00755 if(clickFlag){
00756 missed++ ;
00757 d->pushEvent("missed one change");
00758 }
00759 clickFlag=true ;
00760 dst = det ;
00761 dl = ilb+ random() % (iub-ilb);
00762 }
00763 ms = myCheckForMouseClick() ;
00764 if(ms==2) exitFlag = true ;
00765 det = d->getTimerValue() ;
00766
00767 if(clickFlag && ms==1){
00768 clickFlag = false ;
00769 tet = d->getTimerValue() ;
00770 reactionTimes.push_back(tet-tst);
00771 d->pushEvent("reaction time :" + stringify(tet-tst));
00772 }else{if(ms==1) wrongclick++ ;}
00773 }
00774
00775 long et = d->getTimerValue();
00776 motor->setMotor(0) ;
00777
00778 d->pushEvent("manipulation ends") ;
00779 d->pushEvent("maniupulation time : "+stringify(et-st)) ;allTiming.push_back(et-st);
00780 d->clearScreen();
00781 string answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size());
00782
00783 bool af = false ;
00784 af = isAnswerCorrect(testString,answer,1);
00785 d->pushEvent("subject keyed : "+answer);
00786 d->pushEvent("avarage reaction time : "+ stringify(getAvarage(reactionTimes))) ;
00787 d->pushEvent("number of missed events : "+stringify(missed));
00788 d->pushEvent("number of caught events : "+stringify(reactionTimes.size())) ;
00789 if(missed <= max_miss && getAvarage(reactionTimes)<= min_reaction_time && wrongclick <= max_wrong){
00790 cr++;
00791 d->pushEvent("valid trial");
00792 if(af){
00793 d->pushEvent("answer was correct");sssr++;correctAnswersTiming.push_back(et-st) ;
00794 }else{
00795 d->pushEvent("answer was incorrect");fssr++; incorrectAnswersTiming.push_back(et-st);
00796 }
00797 }else{
00798 if(wrongclick > max_wrong) {
00799 d->displayText("Trial failed, too many FALSE REPORT! Click to start over!");
00800 d->waitForMouseClick();
00801 }
00802 if(missed > max_miss) {
00803 d->displayText("Trial failed, too many events missed! Click to start over!");
00804 d->waitForMouseClick();
00805 }
00806 if(getAvarage(reactionTimes) > min_reaction_time){
00807 d->displayText("Trial failed, reaction slower than limit! Click to start over!");
00808 d->waitForMouseClick();
00809 }
00810 if(af){
00811 d->pushEvent("answer was correct");ssfr++;
00812 }else{
00813 d->pushEvent("answer was incorrect");fsfr++;
00814 }
00815 d->pushEvent("invalid trial");
00816 }
00817
00818 }else{
00819 d->pushEvent("+++++++++++++++++++++++++++++++++++++++") ;
00820 d->showCursor(true);
00821 d->displayText("click one of the mouse buttons to start!");
00822 d->waitForMouseClick() ;
00823 d->showCursor(false) ;
00824 string testString ;
00825 testString = getARandomString(stringSize, argMap["alphabet"] , meticThreshold);
00826 d->clearScreen() ;
00827 d->displayFixationBlink();
00828 d->displayText(testString,true,0) ;
00829 d->waitFrames(onsetDel) ;
00830 d->clearScreen() ;
00831 if(argMap["mask"].compare("y")==0) showMask(mask_onset_frames,argMap["alphabet"]);
00832 if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00833 d->displayFixationBlink(d->getWidth()/2,d->getHeight()/2,1,3);
00834 d->pushEvent("the memorization sequence is : "+testString) ;
00835
00836 d->pushEvent("subject is being challenged for simple momorization");
00837 d->clearScreen();
00838
00839 string answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size());
00840
00841 bool af = false ;
00842 af = isAnswerCorrect(testString,answer,0);
00843 d->pushEvent("subject keyed : "+answer);
00844 if(af){
00845 d->pushEvent("correct answer");
00846 sm++;
00847 }else{
00848 d->pushEvent("incorrect answer");
00849 fm++ ;
00850 }
00851
00852 }
00853 }
00854
00855 d->pushEvent("number of successful memory tests :" + stringify(sm));
00856 d->pushEvent("number of failed memory tests :" + stringify(fm)) ;
00857 d->pushEvent("number of successful sorting and successful reaction trials :"+stringify(sssr));
00858 d->pushEvent("number of successful sorting and failed reaction trials :"+stringify(ssfr));
00859 d->pushEvent("number of failed sorting and successful reaction trials :"+stringify(fssr));
00860 d->pushEvent("number of failed sorting and failed reaction trials :"+stringify(fsfr));
00861 d->pushEvent("avarage time for respond :"+ stringify(getAvarage(allTiming)));
00862 d->pushEvent("variance of respond :"+ stringify(getVariance(allTiming)));
00863 d->pushEvent("avarage time for correct answers "+stringify(getAvarage(correctAnswersTiming))) ;
00864 d->pushEvent("variance of correct responds :"+ stringify(getVariance(correctAnswersTiming)));
00865 d->clearScreen();
00866 d->displayText("Experiment complete. Thank you!");
00867 d->waitForMouseClick();
00868 Mix_FreeChunk( audio_chunk );
00869 Mix_CloseAudio();
00870
00871 manager.stop();
00872
00873
00874
00875 return 0;
00876 }
00877
00878 #endif // INVT_HAVE_LIBSDL_IMAGE
00879