psycho-concurrent-digit.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/psycho-concurrent-digit.C Psychophysics display of still images for concurrent task */
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/psycho-concurrent-digit.C $
00035 // $Id: psycho-concurrent-digit.C 10794 2009-02-08 06:21:09Z itti $
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 
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 ModelManager manager("Psycho-Concurrent-Digit");
00085 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00086 map<uint,uint> testMap ;
00087 map<string,string> argMap ;
00088 map<string,vector<SDL_Rect*>*> clipsmap;
00089 
00090 //////////////////////////////////////////////
00091 
00092 // a functionf for stringigying things
00093 template <class T> std::string stringify(T i)
00094 {
00095         ostringstream o ;
00096         o << i ;
00097         return o.str();
00098 }
00099 
00100 
00101 //////////////////////////////////////////////
00102 void getMouseEvent(){
00103         bool quit = false ;
00104         SDL_Event event ;
00105          while( quit == false ) {
00106                 while( SDL_PollEvent( &event ) ) {
00107                         if( event.type == SDL_MOUSEBUTTONDOWN  ) { quit = true; }
00108                 }
00109         }
00110 }
00111 //pushes back the name of files in the directory into the given vector
00112 int getdir (string dir, vector<string> &files)
00113 {
00114     DIR *dp;
00115     struct dirent *dirp;
00116     if((dp  = opendir(dir.c_str())) == NULL) {
00117         cout << "Error(" << errno << ") opening " << dir << endl;
00118         return errno;
00119     }
00120     string fn = "" ;
00121     size_t found;
00122     string extension = "" ;
00123     while ((dirp = readdir(dp)) != NULL) {
00124         fn = string(dirp->d_name) ;
00125         found = fn.find_last_of(".");
00126         if(found > 0 && found <1000){
00127                 extension = fn.substr(found) ;
00128                 if(extension.compare(".png")== 0 || extension.compare(".jpg")==0 )
00129                 files.push_back(dir+"/"+fn);
00130         }
00131     }
00132     closedir(dp);
00133     return 0;
00134 }
00135 
00136 bool itIsInThere(int x , vector<int> bag){
00137         for( uint i=0 ; i < bag.size(); i++ ){
00138           if(x == bag[i]) return true ;
00139         }
00140         return false ;
00141 }
00142 
00143 ////////////////////////////////////////////////////////
00144 ///// simply generates a sequence of digits displayed on random places on the screen
00145 ////////////////////////////////////////////////////////
00146 string digitMemorizationTask(uint l, int maxForDigit=10 ,float wp = 1.0f, float hp = 1.0f, int displayFrame = 10 , int delayFrame = 30 ){
00147   d->clearScreen() ;
00148   vector<int> pickedones = vector<int>() ;
00149   string test = string("") ;
00150   string tp = string("") ;
00151   int widthRange = (int)((float)(d->getWidth()) * wp);
00152   int heightRange = (int)((float)(d->getHeight()) * hp);
00153   int wMargin = (d->getWidth() - widthRange)/2 ;
00154   int hMargin = (d->getHeight() - heightRange) / 2 ;
00155   for(uint i = 0 ; i < l ; i++){
00156     int nd;
00157     do{ nd= rand()% maxForDigit ; }while(itIsInThere(nd,pickedones) && pickedones.size() < 11) ;
00158     pickedones.push_back(nd);
00159     tp = stringify(nd) ;
00160 //     int x = (rand()%widthRange)  + wMargin;
00161 //     int y = (rand()%heightRange ) + hMargin ;
00162     //d->displayText(tp,Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00163     test += tp ;
00164     //d->waitFrames(displayFrame) ;
00165     d->clearScreen() ;
00166     //if(i<l-1)
00167     //d->waitFrames(delayFrame) ;
00168   }
00169 
00170         int x = (rand()%widthRange)  + wMargin;
00171         int y = (rand()%heightRange ) + hMargin ;
00172         d->displayText(test,Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00173         d->waitFrames(displayFrame*l) ;
00174         return test ;
00175 }
00176 
00177 
00178 ////////////////////////////////////////////////////////
00179 ///// simply generates a sequence of digits displayed on random places on the screen
00180 ////////////////////////////////////////////////////////
00181 string unlimitedDigitMemorizationTask(int maxForDigit=10 ,float wp = 1.0f, float hp = 1.0f, int displayFrame = 30 , int delayFrame = 30){
00182         vector<int> pickedones = vector<int>() ;
00183 
00184         string test = string("") ;
00185         string tp = string("") ;
00186         int widthRange = (int)((float)(d->getWidth()) * wp);
00187         int heightRange = (int)((float)(d->getHeight()) * hp);
00188         int wMargin = (d->getWidth() - widthRange)/2 ;
00189         int hMargin = (d->getHeight() - heightRange) / 2 ;
00190         //bool flag = true ;
00191         SDL_Event event;
00192 
00193 
00194         while( true ){
00195                 d->clearScreen() ;
00196                 while( SDL_PollEvent(&event) != 0 ){
00197                         if (event.type == SDL_MOUSEBUTTONDOWN && event.button.button == SDL_BUTTON_LEFT) return test ;
00198                 }
00199                 d->waitFrames(delayFrame) ;
00200                 int nd;
00201                 do{ nd= rand()% maxForDigit ; }while(itIsInThere(nd,pickedones) && pickedones.size() < 11) ;
00202                 pickedones.push_back(nd);
00203                 tp = stringify(nd) ;
00204 //                 int x = (rand()%widthRange)  + wMargin;
00205 //                 int y = (rand()%heightRange ) + hMargin ;
00206 //                 d->displayText(tp,Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00207                 test += tp ;
00208 //                 d->waitFrames(displayFrame) ;
00209 //                 d->clearScreen() ;
00210         }
00211         int x = (rand()%widthRange)  + wMargin;
00212         int y = (rand()%heightRange ) + hMargin ;
00213         d->displayText(test,Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00214         d->waitFrames(displayFrame) ;
00215         return test ;
00216 }
00217 
00218 
00219 ////////////////////////////////////////////////////////
00220 ///////this will change the order of elements in a vector to a random order
00221 ////////////////////////////////////////////////////////
00222 void scramble(vector<string>& v){
00223         vector<string> tv = vector<string>() ;
00224         while(v.size()>0){
00225                 tv.push_back(v[0]);
00226                 v.erase(v.begin());
00227         }
00228         int i = 0 ;
00229         while(tv.size()>0){
00230                 i = rand()%tv.size() ;
00231                 v.push_back(tv[i]);
00232                 tv.erase(tv.begin()+i);
00233         }
00234 }
00235 
00236 
00237 ////////////////////////////////////////////////////////////////
00238 ////This is our button factory
00239 ////////////////////////////////////////////////////////////////
00240 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){
00241   Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00242   textIm.clear(bgcolor);
00243   writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00244   SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00245   Uint32 bc = d->getUint32color(bordercolor);
00246   drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00247   SDL_Surface* blank =getABlankSurface(size.i , size.j);
00248   SDL_Rect clip;
00249   clip.x = 0 ;
00250   clip.y = 0 ;
00251   clip.w = size.i ;
00252   clip.h = size.j ;
00253   apply_surface(0,0,*surf,*blank,clip);
00254   dumpSurface(surf) ;
00255   return blank ;
00256 }
00257 
00258 ////////////////////////////////////////////////////////////////////////
00259 ////This is the function for creating the keypad, in fact it generates
00260 ////12 buttons and associates the actions to the region for each button
00261 ////////////////////////////////////////////////////////////////////////
00262 
00263 SDL_Surface* getKeyPad(map<string , SDL_Rect>& buttmap){
00264   SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00265   SDL_Rect clip;
00266   clip.x=0;
00267   clip.y=0;
00268   clip.w= pad->w / 3 ;
00269   clip.h = pad->h / 4 ;
00270   //keys for 1 to 9
00271   for( int i = 1 ; i < 10 ; i++){
00272     SDL_Surface* but = getButtonImage(stringify(i),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / 3 , pad->h / 4),PixRGB<byte>(255, 98 , 25),3);
00273     SDL_Rect cl ;
00274     cl.x = ((i-1)%3)*(pad->w)/3 ; cl.y= ((i-1)/3)*((pad->h)/4) ;
00275     cl.w = clip.w ;
00276     cl.h = clip.h ;
00277     apply_surface( cl.x , cl.y ,*but,*pad,clip);
00278     buttmap[stringify(i)] = cl ;
00279     dumpSurface(but);
00280   }
00281   SDL_Rect cl1 ;
00282   cl1.x = 0 ; cl1.y= 3*((pad->h)/4) ;
00283   cl1.w = clip.w ;
00284   cl1.h = clip.h ;
00285   buttmap["z"] = cl1 ;
00286   SDL_Surface* but = getButtonImage(string("<-"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / 3 , pad->h / 4),PixRGB<byte>(255, 98 , 25),3);
00287   apply_surface(0, 3*((pad->h)/4),*but,*pad,clip);
00288   dumpSurface(but);
00289   SDL_Rect cl2 ;
00290   cl2.x = (pad->w)/3 ; cl2.y= 3*((pad->h)/4) ;
00291   cl2.w = clip.w ;
00292   cl2.h = clip.h ;
00293   buttmap["0"] = cl2 ;
00294   but = getButtonImage(string("0"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / 3 , pad->h / 4),PixRGB<byte>(255, 98 , 25),3);
00295   apply_surface((pad->w)/3, 3*((pad->h)/4),*but,*pad,clip);
00296   dumpSurface(but);
00297   SDL_Rect cl3 ;
00298   cl3.x = 2*(pad->w)/3 ; cl3.y= 3*((pad->h)/4) ;
00299   cl3.w = clip.w ;
00300   cl3.h = clip.h ;
00301   buttmap["o"] = cl3 ;
00302   but = getButtonImage(string("Ok"),PixRGB<byte>(0,0,0),PixRGB<byte>(255,255,255),Point2D<int>(pad->w / 3 , pad->h / 4),PixRGB<byte>(255, 98 , 25),3);
00303   apply_surface(2*(pad->w)/3, 3*((pad->h)/4),*but,*pad,clip);
00304   dumpSurface(but);
00305         return pad ;
00306 }
00307 
00308 
00309 
00310 
00311 ///////////////////////////////////////////////////////////////////////////
00312 /////this function listens to mouse clicks and then finds the region of the screen
00313 /////associated with the action, buttmap is the map of the region, offset is the offset of
00314 /////buttons
00315 ///////////////////////////////////////////////////////////////////////////
00316 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00317         int quit = 0 ;
00318         string s ;
00319         SDL_Event event ;
00320         while( quit!=2 ){
00321                  while( SDL_PollEvent( &event ) ) {
00322                    if(event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT ){
00323                      for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00324                        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) {
00325                          quit = 2 ;
00326                          s = it->first ;
00327                          break;
00328                        }
00329 
00330                      }
00331                    }
00332 
00333                 }
00334         }
00335         return s ;
00336 
00337 }
00338 
00339 
00340 ////////////////////////////////////////////////////
00341 ////This function creates a virtual keypad, creates a map of buttons
00342 ////and their representation area and listens to the button press and at
00343 ////the end returns the keyed digits
00344 ////////////////////////////////////////////////////
00345 string getDigitSequenceFromSubject(uint maxl = 7 ){
00346         d->showCursor(true) ;
00347         //let's creat a map to map actions to regions of the screen, each region is represented as an SDL_Rect
00348         map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00349         //now let's get the keypad surface while we get the actions map to regions
00350         SDL_Surface * keypad = getKeyPad(*buttmap);
00351         //this will be the offset of displaying the keypad on the screen
00352         SDL_Rect offset ;
00353         offset.x = (d->getWidth() - keypad->w) /2;
00354         offset.y = (d-> getHeight() - keypad->h) /2;
00355         //now let's display the keypad
00356         d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00357         //this will hold the final string keyed be the subject
00358         string p = string("") ;
00359         //this is a temporary string holding the last action related to the pressed key
00360         string tp = string("");
00361         //now let's record subject's key press
00362         while( tp.compare("o")!=0 ){
00363                 //this button is actually the display for the current string
00364                 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) ;
00365                 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00366                 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00367                 //now let's listen to button events
00368                 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00369                 dumpSurface(dp) ;
00370                 if(tp.compare("z")==0 && p.size()>=0 ) {
00371                         if (p.size()>0) p = p.substr(0,p.size()-1) ;
00372                 }else{
00373                   if(p.size() < maxl && tp.compare("o")!=0) {
00374                                 p +=tp ;
00375                         }
00376 
00377                 }
00378 
00379         }
00380         buttmap = 0 ;
00381         dumpSurface(keypad) ;
00382         d->clearScreen() ;
00383         return p ;
00384 
00385 }
00386 
00387 
00388 
00389 ////////////////////////////////////////////////////////////////////
00390 //// gets a string as the argument and returns a string composed of
00391 //// characters of the first string sorted in the ascending order
00392 ///////////////////////////////////////////////////////////////////
00393 string ascSort(string st)
00394 {
00395   string res = "" ;
00396   vector<string> v = vector<string>();
00397   for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00398 
00399   std::sort(v.begin(), v.end());
00400 
00401   for ( uint i = 0 ; i < v.size() ; i++ ){
00402     res += v[i] ;
00403   }
00404   return res;
00405 }
00406 
00407 ////////////////////////////////////////////////////////////////////
00408 //// gets a string as the argument and returns a string composed of
00409 //// characters of the first string sorted in the descending order
00410 ///////////////////////////////////////////////////////////////////
00411 string desSort(string st)
00412 {
00413   string res = "" ;
00414   vector<string> v = vector<string>();
00415   for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00416   std::sort(v.begin(), v.end());
00417   std::reverse(v.begin(), v.end());
00418   for ( uint i = 0 ; i < v.size() ; i++ ){
00419     res += v[i] ;
00420   }
00421   return res;
00422 }
00423 
00424 ///////////////////////////////////////////////////////////////
00425 //////gets the test string, answer and the mode and identifies if
00426 //////the answer matches the thing it should be, mode=0 checks if
00427 //////if the answer and test string simply the same, mode=1 matches
00428 //////the answer against the ascending sorted string of the test string
00429 //////mode=2 compares the answer against the descending sorted of
00430 //////the test string
00431 ///////////////////////////////////////////////////////////////
00432 bool isAnswerCorrect(string test , string answer , int mode){
00433 
00434   if(mode == 0 && answer.compare(test)==0) return true ;
00435 
00436   if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00437 
00438   if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00439 
00440   return false;
00441 }
00442 
00443 
00444 
00445 int addArgument(const string st,const string delim="="){
00446         int i = st.find(delim) ;
00447         argMap[st.substr(0,i)] = st.substr(i+1);
00448 
00449         return 0 ;
00450 }
00451 
00452 std::string getArgumentValue(string arg){
00453         return argMap[arg] ;
00454 }
00455 
00456 std::string getUsageComment(){
00457 
00458         string com = string("\nlist of arguments : \n");
00459 
00460         com += "\ndelay-interval=[>1]:[>1] (the interval for random delay after stroop task) {default=10}\n";
00461         com += "\nfixation-blink=[y/n] (show the blink for fixation after stroop task or no) {defaule y}\n";
00462         com += "\nimage-dir=[path to image directory] (needed for mode 2 and 3) {default=60:160} \n"  ;
00463         com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00464         com += "\nmemo=[a_string_without_white_space]\n";
00465         com += "\nmode=[1..5] (1 memorization only , 2 dynamic memorization only (ending with evens ascending and ending with odds discending)"
00466                         ", 3 memorization + image display , 4 for dynamic memorization + image display "
00467                         "5 for image display only ) {default=1}\n";
00468         com += "\ndigit-test-size=[<1](number of words in the stroop task){default=6} \n" ;
00469         com += "\nsubject=[subject_name] \n" ;
00470         com += "\ntest-rounds=[>1] (needed for mode1) {default=5}\n";
00471         com += "\ndigit-onset=[>1] (number of frames that the digit will remain onset per digit){default=10}\n";
00472         com += "\ndigit-offset=[>1](number of frames that between two consequent digit onset){default=30}\n";
00473         com += "\nwidth-range=[1..100](the percentage of the width of screen for showing the digits){default=100}\n";
00474         com += "\nheight-range=[1..100](the percentage of the height of screen for showing the digits){default=100}\n";
00475         com += "\nblink-num=[>1](number of blinking of fixation cross){default=3} \n";
00476         com += "\nblink-delay=[>1](delay for blinking cross apprearnce on the screen){default=2}\n";
00477         com += "\ncalib-refresh-period=[>1](number of tests between two calibration){default=12} \n";
00478         return com ;
00479 }
00480 
00481 
00482 extern "C" int main(const int argc, char** argv)
00483 {
00484 
00485           MYLOGVERB = LOG_INFO;  // suppress debug messages
00486         //let's push the initial value for the parameters
00487         argMap["mode"] = "1" ;
00488         argMap["logfile"]="psycho-digit-concurrent.psy" ;
00489         argMap["digit-test-size"]="6" ;
00490         argMap["image-dir"]="..";
00491         argMap["test-rounds"]="5";
00492         argMap["delay-interval"]="60:160" ;
00493         argMap["subject"]="" ;
00494         argMap["memo"]="" ;
00495         argMap["fixation-blink"]="y" ;
00496         argMap["digit-onset"]="10" ;
00497         argMap["digit-offset"]="30" ;
00498         argMap["width-range"]="100" ;
00499         argMap["height-range"]="100" ;
00500         argMap["blink-num"]="3" ;
00501         argMap["blink-delay"]="2" ;
00502         argMap["calib-refresh-period"] = "12" ;
00503         manager.addSubComponent(d);
00504         nub::soft_ref<EventLog> el(new EventLog(manager));
00505         manager.addSubComponent(el);
00506         nub::soft_ref<EyeTrackerConfigurator>
00507                         etc(new EyeTrackerConfigurator(manager));
00508           manager.addSubComponent(etc);
00509 
00510         if (manager.parseCommandLine(argc, argv,
00511             "at least one argument needed", 1, -1)==false){
00512                     cout<<getUsageComment()<<endl;
00513                         return(1);
00514             }
00515 
00516         for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00517                 addArgument(manager.getExtraArg(i),std::string("=")) ;
00518         }
00519 
00520         manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00521         manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00522           // hook our various babies up and do post-command-line configs:
00523         nub::soft_ref<EyeTracker> et = etc->getET();
00524         d->setEyeTracker(et);
00525         d->setEventLog(el);
00526          et->setEventLog(el);
00527 
00528 
00529   // let's get all our ModelComponent instances started:
00530           manager.start();
00531         for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00532   // let's display an ISCAN calibration grid:
00533           d->clearScreen();
00534           d->displayISCANcalib();
00535           d->waitForMouseClick();
00536 
00537   // let's do an eye tracker calibration:
00538           d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00539           int c = d->waitForMouseClick();
00540           if (c == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00541 
00542           d->clearScreen();
00543           int calibPeriod = atoi(argMap["calib-refresh-period"].c_str());
00544 
00545         int blinkNum = atoi(argMap["blink-num"].c_str());
00546         int blinkDelay = atoi(argMap["blink-delay"].c_str());
00547         //let's see in what mode the user like to run the program
00548         int mode = atoi(argMap["mode"].c_str()) ;
00549         //mode 1 and 2 inlude single memorization task, 1 for just memorization and 2 for dynamic memorization
00550         //in dynamic memorization the subject has to sort the string in ascending order when the last digit is even
00551         //and descending order if the last digit is odd
00552         if(mode==1 || mode==2 ){
00553           int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00554           int stringSize = atoi(argMap["digit-test-size"].c_str()) ;
00555           string::size_type position = argMap["delay-interval"].find(":");
00556           int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00557           int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00558           float wr = ((float)(atoi(argMap["width-range"].c_str())))/100.0f;
00559           float hr = ((float)(atoi(argMap["height-range"].c_str())))/100.0f;
00560           int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00561           int offsetDel = atoi(argMap["digit-offset"].c_str()) ;
00562 
00563           for(int i = 0 ; i < numOfTests ; i++){
00564             d->pushEvent("**************************************") ;
00565             d->showCursor(true);
00566             d->displayText("click one of the  mouse buttons to start!");
00567             d->waitForMouseClick() ;
00568             d->showCursor(false);
00569            // d->clearScreen();
00570             string  testString ;
00571             if(stringSize == 0 ){
00572                     testString = unlimitedDigitMemorizationTask( 10 , wr , hr ,  onsetDel ,  offsetDel);
00573             }else{
00574                     testString = digitMemorizationTask(stringSize, 10 , wr , hr ,  onsetDel ,  offsetDel) ;
00575             }
00576             //
00577             d->pushEvent("the memorization sequence is : "+testString) ;
00578             d->waitFrames((rand()%(maxDel - minDel)) +minDel);
00579             string  answer = getDigitSequenceFromSubject(testString.size());
00580             bool af = false ;
00581             if(mode==1){
00582               af = isAnswerCorrect(testString,answer,0);
00583             }else{
00584               int m = atoi(testString.substr(testString.size()-1).c_str()) % 2 ;
00585               switch( m ){
00586                 case 0 : af = isAnswerCorrect(testString , answer , 1 ) ; break ;
00587                 case 1 : af = isAnswerCorrect(testString , answer , 2 ) ; break ;
00588               }
00589 
00590             }
00591             d->pushEvent("subject keyed : "+answer);
00592             if(af){
00593               d->pushEvent("answer was correct");
00594             }else{
00595               d->pushEvent("answer was incorrect");
00596             }
00597 
00598           }
00599         }
00600 
00601         //mode 3 and 4 is reserved for concurrent task; 3 for simple memorization + free viewing
00602         //; 4 for dynamic memorization + free viewing again in dynamic one . Again for strings ending with odd numbers descending
00603         //sorting is required while for strings ending with even digits ascending order is required
00604         if(mode == 3 || mode == 4){
00605                 string::size_type position = argMap["delay-interval"].find(":");
00606                 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00607                 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00608                 int stringSize = atoi(argMap["digit-test-size"].c_str()) ;
00609                 string dir = argMap["image-dir"];
00610                 vector<string> files = vector<string>();
00611                 getdir(dir,files);
00612                 float wr = ((float)(atoi(argMap["width-range"].c_str())))/100.0f;
00613                 float hr = ((float)(atoi(argMap["height-range"].c_str())))/100.0f;
00614                 int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00615                 int offsetDel = atoi(argMap["digit-offset"].c_str()) ;
00616                 int c = 0 ;
00617                 while(files.size()>0){
00618                         c++ ;
00619                         if(c%calibPeriod == 0){
00620 // let's do an eye tracker calibration:
00621                                 d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00622                                 int cl = d->waitForMouseClick();
00623                                 if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00624                                 d->clearScreen();
00625                         }
00626                         int imageIndex = rand()%files.size() ;
00627                         SDL_Surface *surf = load_image(files[imageIndex]);
00628                         float r1 = (float)d->getWidth()/(float)surf->w ;
00629                         float r2 = (float)d->getHeight() / (float)surf->h ;
00630                         surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00631                         SDL_Rect offset;
00632                         offset.x = (d->getWidth() - surf->w) /2;
00633                         offset.y = (d-> getHeight() - surf->h) /2;
00634                         d->pushEvent("**************************************") ;
00635                         d->showCursor(true);
00636                         d->displayText("click a mouse button to start!");
00637                         d->waitForMouseClick() ;
00638                         d->showCursor(false);
00639                         string  testString ;
00640                         if(stringSize == 0 ){
00641                                 testString = unlimitedDigitMemorizationTask( 10 , wr , hr ,  onsetDel ,  offsetDel);
00642                         }else{
00643                                 testString = digitMemorizationTask(stringSize, 10 , wr , hr ,  onsetDel ,  offsetDel) ;
00644                         }
00645                         d->pushEvent("the memorization sequence is : "+testString) ;
00646 
00647                         d->clearScreen() ;
00648                         d->waitNextRequestedVsync(false, true);
00649                         d->pushEvent(std::string("===== Showing image: ") +
00650                                            files[imageIndex] + " =====");
00651                         // start the eye tracker:
00652                         et->track(true);
00653                               //blink the fixation:
00654                         if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink(-1,-1,blinkNum,blinkDelay);
00655                         d->pushEvent("image will go up");
00656                         d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00657                         d->waitFrames((rand()%(maxDel-minDel)) +minDel );
00658                         d->clearScreen() ;
00659                         d->pushEvent("image is down");
00660                         dumpSurface(surf);
00661                         // stop the eye tracker:
00662                         usleep(50000);
00663                              et->track(false);
00664                         //see if the subject was looking at the screen!
00665                         string  answer = getDigitSequenceFromSubject(testString.size());
00666                         bool af = false ;
00667                         if(mode==3){
00668                           af = isAnswerCorrect(testString,answer,0);
00669                         }else{
00670                           int m = atoi(testString.substr(testString.size()-1).c_str()) % 2 ;
00671                           switch( m ){
00672                             case 0 : af = isAnswerCorrect(testString , answer , 1 ) ; break ;
00673                             case 1 : af = isAnswerCorrect(testString , answer , 2 ) ; break ;
00674                           }
00675 
00676                         }
00677                         d->pushEvent("subject keyed : "+answer);
00678                         if(af){
00679                           d->pushEvent("answer was correct");
00680                         }else{
00681                           d->pushEvent("answer was incorrect");
00682                         }
00683                         d->clearScreen() ;
00684                         files.erase(files.begin()+imageIndex);
00685                 }
00686         }
00687 
00688         //mode 5 is reserved for simple free viewing task
00689         if(mode == 5){
00690                 string::size_type position = argMap["delay-interval"].find(":");
00691                 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00692                 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00693                 string dir = argMap["image-dir"];
00694                 vector<string> files = vector<string>();
00695                 getdir(dir,files);
00696                 int c = 0 ;
00697 
00698                 while(files.size()>0){
00699                         c++ ;
00700                         if(c%calibPeriod == 0){
00701 // let's do an eye tracker calibration:
00702                                   d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00703                                   int cl = d->waitForMouseClick();
00704                                   if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00705                                   d->clearScreen();
00706                         }
00707                         int imageIndex = rand()%files.size() ;
00708                         //this block turned out to be buggy! so I decided to switch to working with SDL_Surface instead
00709                         //Image< PixRGB<byte> > image =
00710                                         //Raster::ReadRGB(files[imageIndex]);
00711 
00712                         //SDL_Surface *surf = d->makeBlittableSurface(image, true);
00713                         SDL_Surface *surf = load_image(files[imageIndex]);
00714                         float r1 = (float)d->getWidth()/(float)surf->w ;
00715                         float r2 = (float)d->getHeight() / (float)surf->h ;
00716                         surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00717                         SDL_Rect offset;
00718                         offset.x = (d->getWidth() - surf->w) /2;
00719                         offset.y = (d-> getHeight() - surf->h) /2;
00720                         d->waitFrames(45);
00721                         d->waitNextRequestedVsync(false, true);
00722                         d->pushEvent(std::string("===== Showing image: ") +
00723                                            files[imageIndex] + " =====");
00724 
00725                         // start the eye tracker:
00726                         et->track(true);
00727                               //blink the fixation:
00728                         if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink(-1,-1,blinkNum,blinkDelay);
00729 
00730                         d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00731                         d->waitFrames((rand()%(maxDel-minDel)) +minDel );
00732                         dumpSurface(surf);
00733                         // stop the eye tracker:
00734                         usleep(50000);
00735                              et->track(false);
00736                         d->clearScreen() ;
00737                         files.erase(files.begin()+imageIndex);
00738                 }
00739 
00740         }
00741 
00742           d->clearScreen();
00743           d->displayText("Experiment complete. Thank you!");
00744           d->waitForMouseClick();
00745         //getEvent();
00746           // stop all our ModelComponents
00747           manager.stop();
00748 
00749 
00750           // all done!
00751           return 0;
00752 }
00753 
00754 #endif // INVT_HAVE_LIBSDL_IMAGE
00755 
Generated on Sun May 8 08:40:08 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3