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
00070 #ifndef INVT_HAVE_LIBSDL_IMAGE
00071 #include <cstdio>
00072 int main()
00073 {
00074 fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00075 return 1;
00076 }
00077
00078 #else
00079
00080
00081
00082 using namespace std;
00083
00084
00085
00086 ModelManager manager("Psycho-Concurrent-Digit");
00087 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00088 map<uint,uint> testMap ;
00089 map<string,string> argMap ;
00090 map<string,vector<SDL_Rect*>*> clipsmap;
00091
00092
00093
00094
00095 template <class T> std::string stringify(T i)
00096 {
00097 ostringstream o ;
00098 o << i ;
00099 return o.str();
00100 }
00101
00102
00103 double getAvarage(vector<long> v){
00104 double f = 0.0 ;
00105 for( uint i = 0 ; i < v.size() ; i++ ){
00106 f += v[i] ;
00107 }
00108 if (v.size()!=0) return f/v.size() ;
00109 return -1 ;
00110 }
00111
00112 double getVariance(vector<long> v){
00113 double m = getAvarage(v);
00114 double var = 0.0 ;
00115 for( uint i = 0 ; i < v.size(); i++ ){
00116 var += (v[i]-m)*(v[i]-m) ;
00117 }
00118 if (v.size()!=0) return var/v.size() ;
00119 return -1 ;
00120 }
00121
00122
00123
00124
00125
00126
00127
00128 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){
00129 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00130 textIm.clear(bgcolor);
00131 writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00132 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00133 Uint32 bc = d->getUint32color(bordercolor);
00134 drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00135 SDL_Surface* blank =getABlankSurface(size.i , size.j);
00136 SDL_Rect clip;
00137 clip.x = 0 ;
00138 clip.y = 0 ;
00139 clip.w = size.i ;
00140 clip.h = size.j ;
00141 apply_surface(0,0,*surf,*blank,clip);
00142 dumpSurface(surf) ;
00143 return blank ;
00144 }
00145
00146
00147
00148
00149
00150
00151 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00152 SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00153 SDL_Rect clip;
00154 clip.x=0;
00155 clip.y=0;
00156 int numofrows = alphabet.size()/3 +1;
00157 if(alphabet.size()%3 != 0 ) numofrows++ ;
00158 int numofcolumns = 3 ;
00159 clip.w= pad->w / numofcolumns ;
00160 clip.h = pad->h / numofrows ;
00161
00162
00163 for( int i = 0 ; i < numofrows*3 ; i++){
00164 SDL_Surface* but ;
00165 if((uint)i < alphabet.size()){
00166 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);
00167 }else{
00168 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);
00169 }
00170
00171 SDL_Rect cl ;
00172 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00173 cl.w = clip.w ;
00174 cl.h = clip.h ;
00175 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00176 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00177 dumpSurface(but);
00178 }
00179 SDL_Rect cl1 ;
00180 cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00181 cl1.w = clip.w ;
00182 cl1.h = clip.h ;
00183 buttmap["!"] = cl1 ;
00184 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);
00185 apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00186 dumpSurface(but);
00187 SDL_Rect cl2 ;
00188 cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00189 cl2.w = clip.w ;
00190 cl2.h = clip.h ;
00191 buttmap[" "] = cl2 ;
00192 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);
00193 apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00194 dumpSurface(but);
00195 SDL_Rect cl3 ;
00196 cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00197 cl3.w = clip.w ;
00198 cl3.h = clip.h ;
00199 buttmap["*"] = cl3 ;
00200 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);
00201 apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00202 dumpSurface(but);
00203 return pad ;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00215 int quit = 0 ;
00216 string s ;
00217 SDL_Event event ;
00218 while( quit!=2 ){
00219 while( SDL_PollEvent( &event ) ) {
00220 if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT ){
00221 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00222 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) {
00223 quit = 2 ;
00224 s = it->first ;
00225 break;
00226 }
00227
00228 }
00229 }
00230
00231 }
00232 }
00233 return s ;
00234
00235 }
00236
00237
00238
00239
00240
00241
00242
00243 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00244 d->showCursor(true) ;
00245
00246 map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00247
00248 SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00249
00250 SDL_Rect offset ;
00251 offset.x = (d->getWidth() - keypad->w) /2;
00252 offset.y = (d-> getHeight() - keypad->h) /2;
00253
00254 d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00255
00256 string p = string("") ;
00257
00258 string tp = string("");
00259
00260 while( tp.compare("*")!=0 ){
00261
00262 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) ;
00263 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00264 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00265
00266 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00267 dumpSurface(dp) ;
00268 if(tp.compare("!")==0 && p.size()>=0 ) {
00269 if (p.size()>0) p = p.substr(0,p.size()-1) ;
00270 }else{
00271 if(p.size() < maxl && tp.compare("*")!=0) {
00272 p +=tp ;
00273 }
00274
00275 }
00276
00277 }
00278 buttmap = 0 ;
00279 dumpSurface(keypad) ;
00280 d->clearScreen() ;
00281 return p ;
00282
00283 }
00284
00285
00286
00287
00288 int addArgument(const string st,const string delim="="){
00289 int i = st.find(delim) ;
00290 argMap[st.substr(0,i)] = st.substr(i+1);
00291
00292 return 0 ;
00293 }
00294
00295 std::string getArgumentValue(string arg){
00296 return argMap[arg] ;
00297 }
00298
00299 std::string getUsageComment(){
00300
00301 string com = string("\nlist of arguments : \n");
00302
00303 com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00304 com += "\nmemo=[a_string_without_white_space]\n";
00305 com += "\nrange=[x-y](the size of string){default=200-500} \n";
00306 com += "\nsubject=[subject_name] \n" ;
00307 com += "\ndelay=[>0] (number of frames that subject should do subtraction operation){default=30000000}\n";
00308 com += "\ntest-rounds=[>1] (number of tests ) {default=5}\n";
00309 com += "\ndigit-onset=[>1] (number of frames that the string will remain onset ){default=10}\n";
00310 com += "\nsubtraction-step=[>0] (the subtraction number){default=3} ";
00311 com += "\nmin-reaction-time=[>0](minimum value for avarage reaction time in microsecond in order to consider a trial valid){default=1000000}\n" ;
00312 com += "\nmax-miss=[>0](maximum misses in a trial in order to be considered as a valid one){default=10}\n";
00313 com += "\ninterrupt-time-range=[x-y](this defines a range of uniform radom distribution by which the perceptual interruption happens){default=500000-5000000}\n" ;
00314 com += "\nball-radius={0>}(radius of the ball){default=4}\n" ;
00315 com += "\nrgb1=[r-g-b]{default=50-91-255}\n";
00316 com += "\nrgb2=[r-g-b]{default=89-122-255}\n";
00317 com += "\nrgb3=[r-g-b]{default=138-159-255}\n";
00318 return com ;
00319 }
00320
00321 int myCheckForMouseClick()
00322 {
00323 SDL_Event event;
00324
00325 while(SDL_PollEvent(&event))
00326 {
00327 if (event.type == SDL_MOUSEBUTTONDOWN)
00328 {
00329 if(event.button.button == SDL_BUTTON_LEFT) {
00330 return 1 ;
00331 }
00332 if(event.button.button == SDL_BUTTON_RIGHT) {
00333 return 2 ;
00334 }
00335
00336 }
00337
00338 }
00339
00340
00341 return -1;
00342 }
00343
00344
00345
00346 int getClick(){
00347
00348 SDL_Event event;
00349 bool report = false ;
00350 int i = 0;
00351 do {
00352 do { SDL_WaitEvent(&event); } while (event.type != SDL_MOUSEBUTTONDOWN);
00353 if (event.button.button == SDL_BUTTON_LEFT) {
00354 i = 0 ;
00355 report = true ;
00356 }
00357 if (event.button.button == SDL_BUTTON_RIGHT) {
00358 i = 1 ;
00359 report = true ;
00360 }
00361
00362 }while(!report) ;
00363
00364 return i ;
00365
00366 }
00367
00368 int getAllKindOfClick(){
00369
00370 SDL_Event event;
00371 bool report = false ;
00372 int i = 0;
00373 do {
00374 do { SDL_WaitEvent(&event); } while (event.type != SDL_MOUSEBUTTONDOWN);
00375 long st = d->getTimerValue();
00376 long et = st ;
00377
00378 if (event.button.button == SDL_BUTTON_LEFT) {
00379 i = 0 ;
00380 report = true ;
00381 while( et-st < 300000){
00382 et = d->getTimerValue() ;
00383 if(myCheckForMouseClick()==1) return 2 ;
00384 }
00385 }
00386 if (event.button.button == SDL_BUTTON_RIGHT) {
00387 i = 1 ;
00388 report = true ;
00389 }
00390
00391 }while(!report) ;
00392
00393 return i ;
00394
00395 }
00396
00397 int getNext(int i){
00398
00399 int r = 1 ;
00400 if(i == 0 || i == 2) return 1 ;
00401 r = random()%2 ;
00402 if(r == 0) return 0 ;
00403 if(r == 1 ) return 2 ;
00404 return r ;
00405 }
00406
00407 void drawDot(long t , int r , int c , vector<Uint32> colorVector){
00408 int x = d->getWidth()/2 + (int)((d->getWidth()/3)*cos((double)t/1000000)) ;
00409 int y = d->getHeight()/2 + (int)((d->getHeight()/3 )*sin( 0.2 + (double)t/1000000)) ;
00410 SDL_Surface* black = getABlankSurface(d->getWidth(),d->getHeight());
00411
00412 fillCubicRadiant(black,colorVector[c],x,y,r) ;
00413 SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00414 d->displaySDLSurfacePatch(black , &offs , NULL , -2 , false ,true ) ;
00415 dumpSurface(black) ;
00416 }
00417
00418
00419 extern "C" int main(const int argc, char** argv)
00420 {
00421
00422 MYLOGVERB = LOG_INFO;
00423
00424 argMap["experiment"]="subtraction-working-memory-with-saccade-constraint";
00425 argMap["logfile"]="psycho-wm-subtraction-s.psy" ;
00426 argMap["string-size"]="5" ;
00427 argMap["test-rounds"]="5";
00428 argMap["subject"]="" ;
00429 argMap["memo"]="" ;
00430 argMap["digit-onset"]="10" ;
00431 argMap["range"]="200-500";
00432 argMap["delay"]="30000000" ;
00433 argMap["subtraction-step"]="3" ;
00434 argMap["min-reaction-time"]="1000000" ;
00435 argMap["max-miss"]="10" ;
00436 argMap["interrupt-time-range"]= "500000-5000000";
00437 argMap["mode"]="1";
00438 argMap["rgb1"]="50-91-255" ;
00439 argMap["rgb2"]="89-122-255" ;
00440 argMap["rgb3"]="138-159-255" ;
00441 argMap["ball-radius"] = "4" ;
00442 manager.addSubComponent(d);
00443 nub::soft_ref<EventLog> el(new EventLog(manager));
00444 manager.addSubComponent(el);
00445 d->setEventLog(el);
00446
00447 if (manager.parseCommandLine(argc, argv,
00448 "at least one argument needed", 1, -1)==false){
00449 cout<<getUsageComment()<<endl;
00450 return(1);
00451 }
00452
00453 for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00454 addArgument(manager.getExtraArg(i),std::string("=")) ;
00455 }
00456
00457 manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00458
00459
00460
00461
00462 manager.start();
00463 for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00464
00465 d->clearScreen();
00466 d->displayISCANcalib();
00467 d->waitForMouseClick();
00468 d->displayText("Here the experiment starts! click to start!");
00469 d->waitForMouseClick();
00470 d->clearScreen();
00471
00472
00473 int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00474 int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00475 int opDelay = atoi(argMap["delay"].c_str());
00476 int in = argMap["range"].find("-") ;
00477 int rangeU = atoi( argMap["range"].substr(in+1).c_str()) ;
00478 int rangeL = atoi(argMap["range"].substr(0,in).c_str()) ;
00479 int step = atoi(argMap["subtraction-step"].c_str());
00480 int max_miss = atoi(argMap["max-miss"].c_str());
00481 in = argMap["interrupt-time-range"].find("-") ;
00482 long iub = atol(argMap["interrupt-time-range"].substr(in+1).c_str());
00483 long ilb = atol(argMap["interrupt-time-range"].substr(0,in).c_str()) ;
00484 long min_reaction_time = atol(argMap["min-reaction-time"].c_str()) ;
00485 int br = atoi(argMap["ball-radius"].c_str());
00486
00487 int cr = 0 ;
00488 string rgb1 = argMap["rgb1"] ;
00489 string rgb2 = argMap["rgb2"] ;
00490 string rgb3 = argMap["rgb3"] ;
00491 Uint32 color1 = d->getUint32color(PixRGB<byte>(atoi(rgb1.substr(0,rgb1.find_first_of("-")).c_str()), atoi(rgb1.substr(rgb1.find_first_of("-")+1,rgb1.find_last_of("-")-rgb1.find_first_of("-")-1).c_str()), atoi(rgb1.substr(rgb1.find_last_of("-")+1).c_str())));
00492 Uint32 color2 = d->getUint32color(PixRGB<byte>(atoi(rgb2.substr(0,rgb2.find_first_of("-")).c_str()), atoi(rgb2.substr(rgb2.find_first_of("-")+1,rgb2.find_last_of("-")-rgb2.find_first_of("-")-1).c_str()), atoi(rgb2.substr(rgb2.find_last_of("-")+1).c_str())));
00493 Uint32 color3 = d->getUint32color(PixRGB<byte>(atoi(rgb3.substr(0,rgb3.find_first_of("-")).c_str()), atoi(rgb3.substr(rgb3.find_first_of("-")+1,rgb3.find_last_of("-")-rgb3.find_first_of("-")-1).c_str()), atoi(rgb3.substr(rgb3.find_last_of("-")+1).c_str())));
00494 vector<Uint32> colorVector ;
00495 colorVector.push_back(color1) ;
00496 colorVector.push_back(color2) ;
00497 colorVector.push_back(color3) ;
00498
00499 if(argMap["mode"].compare("2")==0){
00500 while( cr <numOfTests ){
00501
00502 vector<long> reactionTimes ;
00503 int missed = 0 ;
00504 d->pushEvent("**************************************") ;
00505 d->showCursor(true);
00506 d->displayText("click one of the mouse buttons to start!");
00507 d->waitForMouseClick() ;
00508 d->showCursor(false) ;
00509 int initialNum = rangeL+ random()%(rangeU-rangeL) ;
00510 d->clearScreen() ;
00511 d->displayFixationBlink();
00512 d->pushEvent("the initial number is: "+stringify(initialNum)) ;
00513 d->displayText(stringify(initialNum),true,0) ;
00514 d->pushEvent("manupulation starts") ;
00515 d->waitFrames(onsetDel) ;
00516 d->clearScreen() ;
00517 long dst = 0 ;
00518 long det = 0 ;
00519 long dl = 0 ;
00520 int cs = 0 ;
00521
00522 dl = ilb+ random() % (iub-ilb);
00523 dst = d->getTimerValue() ;
00524 det = dst ;
00525 long tst = 0 ;
00526 long tet = 0 ;
00527 long st = d->getTimerValue();
00528 long et = st ;
00529 bool clickFlag = false ;
00530
00531 while( et - st < opDelay ){
00532 drawDot(d->getTimerValue(), br , cs ,colorVector);
00533 if (det - dst > dl ){
00534 cs = getNext(cs) ;
00535
00536 tst = d->getTimerValue() ;
00537 if(clickFlag){
00538 missed++ ;
00539 d->pushEvent("missed one change");
00540 }
00541 clickFlag = true ;
00542 dst = tst ;
00543 det = dst ;
00544 dl = ilb+ random() % (iub-ilb);
00545 et= tst ;
00546 }
00547 det = d->getTimerValue() ;
00548 et = det ;
00549 if(clickFlag){
00550 int c = myCheckForMouseClick() ;
00551 if(c==1 || c==2){
00552 clickFlag = false ;
00553 tet = d->getTimerValue() ;
00554 d->pushEvent("reaction time :" + stringify(tet-tst));
00555 reactionTimes.push_back(tet-tst) ;
00556 }
00557
00558 }else{
00559 myCheckForMouseClick() ;
00560 }
00561
00562 }
00563 d->pushEvent("manipulation ends") ;
00564 d->clearScreen();
00565 string answer = getDigitSequenceFromSubject("0123456789" , 3);
00566 d->pushEvent("the reported number: "+answer);
00567 int finalNum = atoi(answer.c_str()) ;
00568 d->pushEvent("number of operations: "+stringify((initialNum-finalNum)/step));
00569 d->pushEvent("avarage reaction time : "+ stringify(getAvarage(reactionTimes))) ;
00570 d->pushEvent("number of missed events : "+stringify(missed));
00571 d->pushEvent("number of caught events : "+stringify(reactionTimes.size())) ;
00572 if(missed < max_miss && getAvarage(reactionTimes)<= min_reaction_time ){
00573 cr++;
00574 d->pushEvent("valid trial");
00575 }else{
00576 if(missed >= max_miss) {
00577 d->displayText("Trial failed, too many events missed! Click to start over!");
00578 d->waitForMouseClick();
00579 }
00580 if(getAvarage(reactionTimes) > min_reaction_time){
00581 d->displayText("Trial failed, reaction slower than limit! Click to start over!");
00582 d->waitForMouseClick();
00583 }
00584 d->pushEvent("invalid trial");
00585 }
00586 }
00587 }
00588
00589 if(argMap["mode"].compare("1")==0){
00590 while( cr <numOfTests ){
00591
00592 vector<long> reactionTimes ;
00593 int missed = 0 ;
00594 d->pushEvent("**************************************") ;
00595 d->showCursor(true);
00596 d->displayText("click one of the mouse buttons to start!");
00597 d->waitForMouseClick() ;
00598 d->showCursor(false) ;
00599 d->clearScreen() ;
00600 d->displayFixationBlink();
00601 d->pushEvent("manupulation starts") ;
00602
00603 d->clearScreen() ;
00604 long dst = 0 ;
00605 long det = 0 ;
00606 long dl = 0 ;
00607 int cs = 0 ;
00608
00609 dl = ilb+ random() % (iub-ilb);
00610 dst = d->getTimerValue() ;
00611 det = dst ;
00612 long tst = 0 ;
00613 long tet = 0 ;
00614 long st = d->getTimerValue();
00615 long et = st ;
00616 bool clickFlag = false ;
00617
00618 while( et - st < opDelay ){
00619 drawDot(d->getTimerValue(), br , cs ,colorVector);
00620 if (det - dst > dl ){
00621 cs = getNext(cs) ;
00622
00623 tst = d->getTimerValue() ;
00624 if(clickFlag){
00625 missed++ ;
00626 d->pushEvent("missed one change");
00627 }
00628 clickFlag = true ;
00629 dst = tst ;
00630 det = dst ;
00631 dl = ilb+ random() % (iub-ilb);
00632 et= tst ;
00633 }
00634 det = d->getTimerValue() ;
00635 et = det ;
00636 if(clickFlag){
00637 int c = myCheckForMouseClick() ;
00638 if(c==1 || c==2){
00639 clickFlag = false ;
00640 tet = d->getTimerValue() ;
00641 d->pushEvent("reaction time :" + stringify(tet-tst));
00642 reactionTimes.push_back(tet-tst) ;
00643 }
00644
00645 }else{
00646 myCheckForMouseClick() ;
00647 }
00648
00649 }
00650 d->pushEvent("manipulation ends") ;
00651 d->clearScreen();
00652 d->pushEvent("avarage reaction time : "+ stringify(getAvarage(reactionTimes))) ;
00653 d->pushEvent("number of missed events : "+stringify(missed));
00654 d->pushEvent("number of caught events : "+stringify(reactionTimes.size())) ;
00655 if(missed < max_miss && getAvarage(reactionTimes)<= min_reaction_time ){
00656 cr++;
00657 d->pushEvent("valid trial");
00658 }else{
00659 if(missed >= max_miss) {
00660 d->displayText("Trial failed, too many events missed! Click to start over!");
00661 d->waitForMouseClick();
00662 }
00663 if(getAvarage(reactionTimes) > min_reaction_time){
00664 d->displayText("Trial failed, reaction slower than limit! Click to start over!");
00665 d->waitForMouseClick();
00666 }
00667 d->pushEvent("invalid trial");
00668 }
00669 }
00670 }
00671
00672 d->clearScreen();
00673 d->displayText("Experiment complete. Thank you!");
00674 d->waitForMouseClick();
00675
00676
00677 manager.stop();
00678
00679
00680
00681 return 0;
00682 }
00683
00684 #endif // INVT_HAVE_LIBSDL_IMAGE
00685