psychoWMS-A.C

00001 /*!@file AppPsycho/psychoWM.C Psychophysics test to measure the influence of eyemovement on memory task performance */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/psychoWMS-A.C $
00035 // $Id: psychoWMS-A.C 12962 2010-03-06 02:13:53Z irock $
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-WMS");
00089 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00090 map<uint,uint> testMap ;
00091 map<string,string> argMap ;
00092 map<string,vector<SDL_Rect*>*> clipsmap;
00093 Mix_Chunk *whitenoise_chunk = NULL;
00094 
00095 //////////////////////////////////////////////
00096 // a functionf for stringigying things
00097 //////////////////////////////////////////////
00098 template <class T> std::string stringify(T i)
00099 {
00100         ostringstream o ;
00101         o << i ;
00102         return o.str();
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 
00125 
00126 //pushes back the name of files in the directory into the given vector
00127 int getdir (string dir, vector<string> &files)
00128 {
00129         DIR *dp;
00130         struct dirent *dirp;
00131         if((dp  = opendir(dir.c_str())) == NULL) {
00132                 cout << "Error(" << errno << ") opening " << dir << endl;
00133                 return errno;
00134         }
00135         string fn = "" ;
00136         size_t found;
00137         string extension = "" ;
00138         while ((dirp = readdir(dp)) != NULL) {
00139                 fn = string(dirp->d_name) ;
00140                 found = fn.find_last_of(".");
00141                 if(found > 0 && found <1000){
00142                         extension = fn.substr(found) ;
00143                         if(extension.compare(".png")== 0 || extension.compare(".jpg")==0 )
00144                                 files.push_back(dir+"/"+fn);
00145                 }
00146         }
00147         closedir(dp);
00148         return 0;
00149 }
00150 
00151 
00152 
00153 ////////////////////////////////////////////////////////////////
00154 ////This is our button factory
00155 ////////////////////////////////////////////////////////////////
00156 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){
00157         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00158         textIm.clear(bgcolor);
00159         writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00160         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00161         Uint32 bc = d->getUint32color(bordercolor);
00162         drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00163         SDL_Surface* blank =getABlankSurface(size.i , size.j);
00164         SDL_Rect clip;
00165         clip.x = 0 ;
00166         clip.y = 0 ;
00167         clip.w = size.i ;
00168         clip.h = size.j ;
00169         apply_surface(0,0,*surf,*blank,clip);
00170         dumpSurface(surf) ;
00171         return blank ;
00172 }
00173 
00174 ////////////////////////////////////////////////////////////////////////
00175 ////This is the function for creating the keypad, in fact it generates
00176 ////12 buttons and associates the actions to the region for each button
00177 ////////////////////////////////////////////////////////////////////////
00178 
00179 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00180         SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00181         SDL_Rect clip;
00182         clip.x=0;
00183         clip.y=0;
00184         int numofrows = alphabet.size()/3 +1;
00185         if(alphabet.size()%3 != 0 ) numofrows++ ;
00186         int numofcolumns = 3 ;
00187         clip.w= pad->w / numofcolumns ;
00188         clip.h = pad->h / numofrows ;
00189 
00190   //keys for 1 to 9
00191         for( int i = 0 ; i < numofrows*3 ; i++){
00192                 SDL_Surface* but ;
00193                 if((uint)i < alphabet.size()){
00194                         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);
00195                 }else{
00196                         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);
00197                 }
00198 
00199                 SDL_Rect cl ;
00200                 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00201                 cl.w = clip.w ;
00202                 cl.h = clip.h ;
00203                 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00204                 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00205                 dumpSurface(but);
00206         }
00207         SDL_Rect cl1 ;
00208         cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00209         cl1.w = clip.w ;
00210         cl1.h = clip.h ;
00211         buttmap["!"] = cl1 ;
00212         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);
00213         apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00214         dumpSurface(but);
00215         SDL_Rect cl2 ;
00216         cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00217         cl2.w = clip.w ;
00218         cl2.h = clip.h ;
00219         buttmap[" "] = cl2 ;
00220         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);
00221         apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00222         dumpSurface(but);
00223         SDL_Rect cl3 ;
00224         cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00225         cl3.w = clip.w ;
00226         cl3.h = clip.h ;
00227         buttmap["*"] = cl3 ;
00228         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);
00229         apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00230         dumpSurface(but);
00231         return pad ;
00232 }
00233 
00234 
00235 
00236 
00237 ///////////////////////////////////////////////////////////////////////////
00238 /////this function listens to mouse clicks and then finds the region of the screen
00239 /////associated with the action, buttmap is the map of the region, offset is the offset of
00240 /////buttons
00241 ///////////////////////////////////////////////////////////////////////////
00242 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00243         int quit = 0 ;
00244         string s ;
00245         SDL_Event event ;
00246         while( quit!=2 ){
00247                 while( SDL_PollEvent( &event ) ) {
00248                         if(event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT ){
00249                                 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00250                                         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) {
00251                                                 quit = 2 ;
00252                                                 s = it->first ;
00253                                                 break;
00254                                         }
00255 
00256                                 }
00257                         }
00258 
00259                 }
00260         }
00261         return s ;
00262 
00263 }
00264 
00265 
00266 ////////////////////////////////////////////////////
00267 ////This function creates a virtual keypad, creates a map of buttons
00268 ////and their representation area and listens to the button press and at
00269 ////the end returns the keyed digits
00270 ////////////////////////////////////////////////////
00271 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00272         d->showCursor(true) ;
00273         //let's creat a map to map actions to regions of the screen, each region is represented as an SDL_Rect
00274         map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00275         //now let's get the keypad surface while we get the actions map to regions
00276         SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00277         //this will be the offset of displaying the keypad on the screen
00278         SDL_Rect offset ;
00279         offset.x = (d->getWidth() - keypad->w) /2;
00280         offset.y = (d-> getHeight() - keypad->h) /2;
00281         //now let's display the keypad
00282         d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00283         //this will hold the final string keyed be the subject
00284         string p = string("") ;
00285         //this is a temporary string holding the last action related to the pressed key
00286         string tp = string("");
00287         //now let's record subject's key press
00288         while( tp.compare("*")!=0 ){
00289                 //this button is actually the display for the current string
00290                 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) ;
00291                 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00292                 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00293                 //now let's listen to button events
00294                 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00295                 dumpSurface(dp) ;
00296                 if(tp.compare("!")==0 && p.size()>=0 ) {
00297                         if (p.size()>0) p = p.substr(0,p.size()-1) ;
00298                 }else{
00299                         if(p.size() < maxl && tp.compare("*")!=0) {
00300                                 p +=tp ;
00301                         }
00302 
00303                 }
00304 
00305         }
00306         buttmap = 0 ;
00307         dumpSurface(keypad) ;
00308         d->clearScreen() ;
00309         return p ;
00310 
00311 }
00312 
00313 
00314 
00315 
00316 int addArgument(const string st,const string delim="="){
00317         int i = st.find(delim) ;
00318         argMap[st.substr(0,i)] = st.substr(i+1);
00319 
00320         return 0 ;
00321 }
00322 
00323 std::string getArgumentValue(string arg){
00324         return argMap[arg] ;
00325 }
00326 
00327 std::string getUsageComment(){
00328 
00329         string com = string("\nlist of arguments : \n");
00330 
00331         com += "\nlogfile=[logfilename.psy] {default = psycho-wms-a.psy}\n" ;
00332         com += "\nmemo=[a_string_without_white_space]\n";
00333         com += "\nrange=[x-y](the size of string){default=200-500} \n";
00334         com += "\nsubject=[subject_name] \n" ;
00335         com += "\ndelay=[>0] (number of frames that subject should do subtraction operation){default=30000000}\n";
00336         com += "\ntest-rounds=[>1] (number of tests ) {default=5}\n";
00337         com += "\ndigit-onset=[>1] (number of frames that the string will remain onset ){default=10}\n";
00338         com += "\nsubtraction-step=[>0] (the subtraction number){default=3} ";
00339         com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00340         com += "\audio-file=[white noise file]{default=audio.wav}\n";
00341         com += "\npuase-frames=[number of frames for stopping the the audio playback]{default=5}\n";
00342         com += "\nmin-reaction-time=[>0](minimum value for avarage reaction time in microsecond in order to consider a trial valid){default=1000000}\n" ;
00343         com += "\nmax-miss=[>0](maximum misses in a trial in order to be  considered as a valid one){default=10}\n";
00344         com += "\ninterrupt-time-range=[x-y](this defines a range of uniform radom distribution by which the perceptual interruption happens){default=500000-5000000}\n" ;
00345         return com ;
00346 }
00347 
00348 int myCheckForMouseClick()
00349 {
00350         SDL_Event event;
00351 
00352         while(SDL_PollEvent(&event))
00353         {
00354                 if (event.type == SDL_MOUSEBUTTONDOWN)
00355                 {
00356                         if(event.button.button == SDL_BUTTON_LEFT) {
00357                                 return 1 ;
00358                         }
00359                         if(event.button.button == SDL_BUTTON_RIGHT) {
00360                                 return 2 ;
00361                         }
00362 
00363                 }
00364       // ignore other events
00365         }
00366 
00367   // there was no event in the event queue:
00368         return -1;
00369 }
00370 
00371 
00372 
00373 int getClick(){
00374     // while (myCheckForMouseClick() != -1) ;
00375         SDL_Event event;
00376         bool report = false ;
00377         int i = 0;  // will be returned if any other button than left or right
00378         do {
00379                 do { SDL_WaitEvent(&event); } while (event.type != SDL_MOUSEBUTTONDOWN);
00380                 if (event.button.button == SDL_BUTTON_LEFT) {
00381                         i = 0 ;
00382                         report = true ;
00383                 }
00384                 if (event.button.button == SDL_BUTTON_RIGHT) {
00385                         i = 1 ;
00386                         report = true ;
00387                 }
00388 
00389         }while(!report) ;
00390 
00391         return i ;
00392 
00393 }
00394 
00395 int getAllKindOfClick(){
00396     // while (myCheckForMouseClick() != -1) ;
00397         SDL_Event event;
00398         bool report = false ;
00399         int i = 0;  // will be returned if any other button than left or right
00400         do {
00401                 do { SDL_WaitEvent(&event); } while (event.type != SDL_MOUSEBUTTONDOWN);
00402                 long st = d->getTimerValue();
00403                 long et = st ;
00404 
00405                 if (event.button.button == SDL_BUTTON_LEFT) {
00406                         i = 0 ;
00407                         report = true ;
00408                         while( et-st < 300000){
00409                                 et = d->getTimerValue() ;
00410                                 if(myCheckForMouseClick()==1) return 2 ;
00411                         }
00412                 }
00413                 if (event.button.button == SDL_BUTTON_RIGHT) {
00414                         i = 1 ;
00415                         report = true ;
00416                 }
00417 
00418         }while(!report) ;
00419 
00420         return i ;
00421 
00422 }
00423 
00424 
00425 extern "C" int main(const int argc, char** argv)
00426 {
00427 
00428         MYLOGVERB = LOG_INFO;  // suppress debug messages
00429         //let's push the initial value for the parameters
00430         argMap["experiment"]="subtraction-working-memory";
00431         argMap["logfile"]="psycho-wms-a.psy" ;
00432         argMap["string-size"]="5" ;
00433         argMap["test-rounds"]="5";
00434         argMap["subject"]="" ;
00435         argMap["memo"]="" ;
00436         argMap["digit-onset"]="10" ;
00437         argMap["range"]="200-500";
00438         argMap["delay"]="30000000" ;
00439         argMap["subtraction-step"]="3" ;
00440         argMap["sound-dir"]="..";
00441         argMap["audio-file"]="audio.wav";
00442         argMap["pause-frames"]="5" ;
00443         argMap["min-reaction-time"]="1000000" ;
00444         argMap["max-miss"]="10" ;
00445         argMap["interrupt-time-range"]= "500000-5000000";
00446         argMap["mode"]="1";
00447 
00448         manager.addSubComponent(d);
00449         nub::soft_ref<EventLog> el(new EventLog(manager));
00450         manager.addSubComponent(el);
00451         d->setEventLog(el);
00452 
00453         if (manager.parseCommandLine(argc, argv,
00454             "at least one argument needed", 1, -1)==false){
00455                     cout<<getUsageComment()<<endl;
00456                     return(1);
00457             }
00458 
00459             for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00460                     addArgument(manager.getExtraArg(i),std::string("=")) ;
00461             }
00462 
00463             manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00464 
00465             if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00466                     LINFO( "did not open the mix-audio") ;
00467                     return -1 ;
00468             }
00469             string noisestr = argMap["sound-dir"] + "/" + argMap["audio-file"];
00470             whitenoise_chunk = Mix_LoadWAV(noisestr.c_str());
00471             if( whitenoise_chunk == NULL  )
00472             {
00473                     LINFO("did not find the indicated wav files!");
00474                     return -1;
00475             }
00476 
00477 
00478 
00479   // let's get all our ModelComponent instances started:
00480             manager.start();
00481             for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00482   // let's display an ISCAN calibration grid:
00483             d->clearScreen();
00484             d->displayISCANcalib();
00485             d->waitForMouseClick();
00486             d->displayText("Here the experiment starts! click to start!");
00487             d->waitForMouseClick();
00488             d->clearScreen();
00489         //let's see in what mode the user like to run the program
00490 
00491             int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00492             int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00493             int opDelay = atoi(argMap["delay"].c_str());
00494             int in = argMap["range"].find("-") ;
00495             int rangeU = atoi( argMap["range"].substr(in+1).c_str()) ;
00496             int rangeL = atoi(argMap["range"].substr(0,in).c_str()) ;
00497             int step = atoi(argMap["subtraction-step"].c_str());
00498             int max_miss = atoi(argMap["max-miss"].c_str());
00499             in  = argMap["interrupt-time-range"].find("-") ;
00500             long iub = atol(argMap["interrupt-time-range"].substr(in+1).c_str());
00501             long ilb = atol(argMap["interrupt-time-range"].substr(0,in).c_str()) ;
00502             long min_reaction_time = atol(argMap["min-reaction-time"].c_str()) ;
00503         //let's count the rounds
00504             int cr = 0 ;
00505             vector<int> speedVector;
00506             speedVector.push_back(110) ;
00507             speedVector.push_back(-110) ;
00508             speedVector.push_back(150) ;
00509             int pause_frames = atoi(argMap["pause-frames"].c_str());
00510 
00511             if(argMap["mode"].compare("2")==0){
00512                     while( cr <numOfTests ){
00513 
00514                             vector<long> reactionTimes ;
00515                             int missed = 0 ;
00516                             d->pushEvent("**************************************") ;
00517                             d->showCursor(true);
00518                             d->displayText("click one of the  mouse buttons to start!");
00519                             d->waitForMouseClick() ;
00520                             d->showCursor(false) ;
00521                             int initialNum = rangeL+ random()%(rangeU-rangeL) ;
00522                             d->clearScreen() ;
00523                             d->displayFixationBlink();
00524                             d->pushEvent("the initial number is: "+stringify(initialNum)) ;
00525                             d->displayText(stringify(initialNum),true,0) ;
00526                             d->pushEvent("manupulation starts") ;
00527                             d->waitFrames(onsetDel) ;
00528                             Mix_PlayChannel( -1, whitenoise_chunk , 300 ) ;
00529                             d->clearScreen() ;
00530                             long dst = 0 ;//keeps the start of each color set
00531                             long det = 0 ;//keeps the current time to be compared with dl
00532                             long dl = 0 ;//this is the number of microseconds for a color display
00533 
00534                             dl = ilb+ random() % (iub-ilb);//let's get a value for the the first color display
00535                             dst = d->getTimerValue() ;//this is the initial time of display of the first color
00536                             det = dst ;
00537                             long tst = 0 ;//tst keeps track of the time new color is presented
00538                             long tet = 0 ;//after tst tet is sampled from clock to see how long it will take for the subject to respond
00539                             long st = d->getTimerValue(); //this will be a sample of clock at the start of the test round
00540                             long et = st ;//this is the current time of process if et-st becomes more than opDelay then we should challenge the subject
00541                             bool clickFlag = false ;
00542 
00543                             while( et - st < opDelay ){
00544 
00545                                     if (det - dst > dl ){//if we get to a point that the bloop should be made
00546 
00547                                             Mix_Pause(-1);
00548                                                 d->waitFrames(pause_frames);
00549                                             Mix_Resume(-1) ;
00550                                            // d->displaySDLSurfacePatch(surfVector[cs] , &offs , NULL , -2 , false ,true ) ;//put up the next color
00551                                             tst = d->getTimerValue() ;//start keeping track of the timer to see how fast the subject will respond
00552                                             if(clickFlag){
00553                                                     missed++ ;
00554                                                     d->pushEvent("missed one change");
00555                                             }
00556                                             clickFlag = true ;
00557                                             dst = tst ;
00558                                             det = dst ; //let's make sure that a new round is set
00559                                             dl = ilb+ random() % (iub-ilb);//we get a value for next stop
00560                                             et= tst ;
00561                                     }
00562                                     det = d->getTimerValue() ;
00563                                     et = det ;
00564                                     if(clickFlag){// && (myCheckForMouseClick()==1 || myCheckForMouseClick()==2)){
00565                                             int c = myCheckForMouseClick() ;
00566                                             if(c==1 || c==2){
00567                                                     clickFlag = false ;
00568                                                     tet = d->getTimerValue() ;
00569                                                     d->pushEvent("reaction time :" + stringify(tet-tst));
00570                                                     reactionTimes.push_back(tet-tst) ;
00571                                             }
00572 
00573                                     }else{
00574                                             myCheckForMouseClick() ;//let's get rid of the queue of the non-related events including the wrong clicks
00575                                     }
00576 
00577                             }
00578                             d->pushEvent("manipulation ends") ;
00579                             Mix_Pause(-1);
00580                             d->clearScreen();
00581                             string  answer = getDigitSequenceFromSubject("0123456789" , 3);
00582                             d->pushEvent("the reported number: "+answer);
00583                             int finalNum = atoi(answer.c_str()) ;
00584                             d->pushEvent("number of operations: "+stringify((initialNum-finalNum)/step));
00585                             d->pushEvent("avarage reaction time : "+ stringify(getAvarage(reactionTimes))) ;
00586                             d->pushEvent("number of missed events : "+stringify(missed));
00587                             d->pushEvent("number of caught events : "+stringify(reactionTimes.size())) ;
00588                                 if(missed < max_miss && getAvarage(reactionTimes)<= min_reaction_time ){
00589                                         cr++;
00590                                         d->pushEvent("valid trial");
00591                                 }else{
00592                                         if(missed >= max_miss) {
00593                                                 d->displayText("Trial failed, too many events missed! Click to start over!");
00594                                                 d->waitForMouseClick();
00595                                         }
00596                                         if(getAvarage(reactionTimes) > min_reaction_time){
00597                                                 d->displayText("Trial failed, reaction slower than limit! Click to start over!");
00598                                                 d->waitForMouseClick();
00599                                         }
00600                                         d->pushEvent("invalid trial");
00601                                 }
00602                     }
00603             }
00604 
00605             if(argMap["mode"].compare("1")==0){
00606                     while( cr <numOfTests ){
00607 
00608                             vector<long> reactionTimes ;
00609                             int missed = 0 ;
00610                             d->pushEvent("**************************************") ;
00611                             d->showCursor(true);
00612                             d->displayText("click one of the  mouse buttons to start!");
00613                             d->waitForMouseClick() ;
00614                             d->showCursor(false) ;
00615                             d->clearScreen() ;
00616                             d->displayFixationBlink();
00617                             d->pushEvent("manupulation starts") ;
00618                             Mix_PlayChannel( -1, whitenoise_chunk , 300 ) ;
00619 
00620                             d->clearScreen() ;
00621                             long dst = 0 ;//keeps the start of each color set
00622                             long det = 0 ;//keeps the current time to be compared with dl
00623                             long dl = 0 ;//this is the number of microseconds for a color display
00624 
00625                             dl = ilb+ random() % (iub-ilb);//let's get a value for the the first color display
00626                             dst = d->getTimerValue() ;//this is the initial time of display of the first color
00627                             det = dst ;
00628                             long tst = 0 ;//tst keeps track of the time new color is presented
00629                             long tet = 0 ;//after tst tet is sampled from clock to see how long it will take for the subject to respond
00630                             long st = d->getTimerValue(); //this will be a sample of clock at the start of the test round
00631                             long et = st ;//this is the current time of process if et-st becomes more than opDelay then we should challenge the subject
00632                             bool clickFlag = false ;
00633 
00634                             while( et - st < opDelay ){
00635 
00636                                     if (det - dst > dl ){//if we get to a point that the bloop should be made
00637                                             Mix_Pause(-1);
00638                                             d->waitFrames(pause_frames);
00639                                             Mix_Resume(-1) ;
00640 
00641                                             tst = d->getTimerValue() ;//start keeping track of the timer to see how fast the subject will respond
00642                                             if(clickFlag){
00643                                                     missed++ ;
00644                                                     d->pushEvent("missed one change");
00645                                             }
00646                                             clickFlag = true ;
00647                                             dst = tst ;
00648                                             det = dst ; //let's make sure that a new round is set
00649                                             dl = ilb+ random() % (iub-ilb);//we get a value for next stop
00650                                             et= tst ;
00651                                     }
00652                                     det = d->getTimerValue() ;
00653                                     et = det ;
00654                                     if(clickFlag){// && (myCheckForMouseClick()==1 || myCheckForMouseClick()==2)){
00655                                             int c = myCheckForMouseClick() ;
00656                                             if(c==1 || c==2){
00657                                                     clickFlag = false ;
00658                                                     tet = d->getTimerValue() ;
00659                                                     d->pushEvent("reaction time :" + stringify(tet-tst));
00660                                                     reactionTimes.push_back(tet-tst) ;
00661                                             }
00662 
00663                                     }else{
00664                                             myCheckForMouseClick() ;//let's get rid of the queue of the non-related events including the wrong clicks
00665                                     }
00666 
00667                             }
00668                             d->pushEvent("manipulation ends") ;
00669                             Mix_Pause(-1);
00670                             d->clearScreen();
00671                             d->pushEvent("avarage reaction time : "+ stringify(getAvarage(reactionTimes))) ;
00672                             d->pushEvent("number of missed events : "+stringify(missed));
00673                             d->pushEvent("number of caught events : "+stringify(reactionTimes.size())) ;
00674                                 if(missed < max_miss && getAvarage(reactionTimes)<= min_reaction_time ){
00675                                         cr++;
00676                                         d->pushEvent("valid trial");
00677                                 }else{
00678                                         if(missed >= max_miss) {
00679                                                 d->displayText("Trial failed, too many events missed! Click to start over!");
00680                                                 d->waitForMouseClick();
00681                                         }
00682                                         if(getAvarage(reactionTimes) > min_reaction_time){
00683                                                 d->displayText("Trial failed, reaction slower than limit! Click to start over!");
00684                                                 d->waitForMouseClick();
00685                                         }
00686                                         d->pushEvent("invalid trial");
00687                                 }
00688                     }
00689             }
00690 
00691             d->clearScreen();
00692             d->displayText("Experiment complete. Thank you!");
00693             d->waitForMouseClick();
00694             Mix_FreeChunk( whitenoise_chunk );
00695             Mix_CloseAudio();
00696         // stop all our ModelComponents
00697             manager.stop();
00698 
00699 
00700         // all done!
00701             return 0;
00702 }
00703 
00704 #endif // INVT_HAVE_LIBSDL_IMAGE
00705 
Generated on Sun May 8 08:40:10 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3