psycho-concurrent-still.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/psycho-concurrent-still.C Psychophysics display of still for concurrent task images */
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-still.C $
00035 // $Id: psycho-concurrent-still.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 
00065 
00066 
00067 
00068 #ifndef INVT_HAVE_LIBSDL_IMAGE
00069 #include <cstdio>
00070 int main()
00071 {
00072         fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00073         return 1;
00074 }
00075 
00076 #else
00077 
00078 
00079 
00080 using namespace std;
00081 // ######################################################################
00082 ModelManager manager("Psycho-Concurrent");
00083 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00084 map<uint,uint> testMap ;
00085 map<string,string> argMap ;
00086 
00087 
00088 //////////////////////////////////////////////
00089 
00090 // a functionf for stringigying things
00091 template <class T> std::string stringify(T i)
00092 {
00093         ostringstream o ;
00094         o << i ;
00095         return o.str();
00096 }
00097 
00098 //////////////////////////////////////////////
00099 void getMouseEvent(){
00100         bool quit = false ;
00101         SDL_Event event ;
00102          while( quit == false ) {
00103                 while( SDL_PollEvent( &event ) ) {
00104                         if( event.type == SDL_MOUSEBUTTONDOWN  ) { quit = true; }
00105                 }
00106         }
00107 }
00108 //pushes back the name of files in the directory into the given vector
00109 int getdir (string dir, vector<string> &files)
00110 {
00111     DIR *dp;
00112     struct dirent *dirp;
00113     if((dp  = opendir(dir.c_str())) == NULL) {
00114         cout << "Error(" << errno << ") opening " << dir << endl;
00115         return errno;
00116     }
00117     string fn = "" ;
00118     size_t found;
00119     string extension = "" ;
00120     while ((dirp = readdir(dp)) != NULL) {
00121         fn = string(dirp->d_name) ;
00122         found = fn.find_last_of(".");
00123         if(found > 0 && found <1000){
00124                 extension = fn.substr(found) ;
00125                 if(extension.compare(".png")== 0 || extension.compare(".jpg")==0 )
00126                 files.push_back(dir+"/"+fn);
00127         }
00128     }
00129     closedir(dp);
00130     return 0;
00131 }
00132 //////////////////////////////////////////////
00133 //inputs: l ; number of words to be shown (1..5)
00134 //        :delay; delay between displaying words in number of frames
00135 
00136 void colorStroopTask(const uint l,const int delay = 10){
00137         //0 stands for white
00138         //1 stands for yellow
00139         //2 stands for red
00140         //3 stands for green
00141         //4 stands for blue
00142         vector<uint> word = vector<uint>() ;
00143         vector<uint> color = vector<uint>() ;
00144         for(uint i = 0 ; i < 5 ; i++){
00145                 word.push_back(i) ;
00146                 color.push_back(i) ;
00147         }
00148         for(uint i = 0 ; i < l ; i++){
00149                 int wi = rand() % word.size() ;
00150                 int ci = rand() % color.size() ;
00151                 //let's make sure that the color word and color are not the same
00152                 while( ci==wi ){
00153                         ci = rand() % color.size() ;
00154                 }
00155 
00156                 testMap[word[wi]] = color[ci] ;
00157                 word.erase(word.begin()+wi);
00158                 color.erase(color.begin()+ci) ;
00159         }
00160 
00161         PixRGB<byte> white(255, 255, 255);
00162         PixRGB<byte> yellow(255, 255, 0);
00163         PixRGB<byte> red(255,0,0);
00164         PixRGB<byte> green(0,255,0) ;
00165         PixRGB<byte> blue(0,0,255) ;
00166         SDL_Surface* blank = getABlankSurface(d->getWidth(),d->getHeight()) ;
00167         for(map<uint,uint>:: iterator  it = testMap.begin() ; it != testMap.end() ; ++it  ){
00168                 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00169                 textIm.clear(PixRGB<byte>(0, 0, 0));
00170                 int x = rand()% (d->getWidth()-60) ;
00171                 int y = rand() % (d-> getHeight() - 60);
00172                 string myword = "" ;
00173                 PixRGB<byte> mycolor(0,0,0) ;
00174                 switch (it->first){
00175                         case 0 : myword = "white"; break ;
00176                         case 1 : myword = "yellow" ; break ;
00177                         case 2 : myword = "red" ; break ;
00178                         case 3 : myword = "green" ; break ;
00179                         case 4 : myword = "blue" ; break ;
00180                 }
00181 
00182                 switch ( it->second){
00183                         case 0 : mycolor = white ; break ;
00184                         case 1 : mycolor = yellow ; break ;
00185                         case 2 : mycolor = red ; break ;
00186                         case 3 : mycolor = green; break ;
00187                         case 4 : mycolor = blue ; break ;
00188                 }
00189                 writeText(textIm, Point2D<int>(x,y), myword.c_str(),mycolor, PixRGB<byte>(0,0,0), SimpleFont::FIXED(10), true);
00190                 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00191                 d->pushEvent(string("stroop test: ")+stringify(it->first)+" " +stringify(it->second)) ;
00192                 d->pushEvent(std::string("image is going up"));
00193                 d->displaySurface(surf, -2);
00194                 d->waitFrames(delay);
00195                 d->pushEvent(std::string("image is going down"));
00196                 d->displaySurface(blank, -2);
00197                 dumpSurface(surf) ;
00198         }
00199         dumpSurface(blank);
00200 }
00201 /////////////////////////////////////////////
00202 //this function poses the question based on the testMap previously set,at the end the testMap will be cleared
00203 void colorStroopQuiz(){
00204         //since the subject is supposed to interact with the mouse we make it appear!
00205         d->showCursor(true);
00206         map<uint,string> abrMap ;
00207         abrMap[2] = "red" ;
00208         abrMap[4] = "blue" ;
00209         abrMap[3] = "green" ;
00210         abrMap[0] = "white" ;
00211         abrMap[1] = "yellow" ;
00212         int rd = rand()%testMap.size() ;
00213         int c = -1 ;
00214         uint word = 0 ;
00215         uint color= 0 ;
00216 
00217         for(map<uint,uint>:: iterator  it = testMap.begin() ; it != testMap.end() ; ++it  ){
00218                 c++ ;
00219                 if(c==rd){
00220                         word = it->first;
00221                         color = it->second;
00222                 }
00223         }
00224         string disWord = abrMap[word] ;
00225         string disColor = abrMap[color]  ;
00226 
00227         //we toss a coin to see what question to ask; asking the color of a word (rd=0) or the word in a give color (rd=1)
00228         rd = rand()%2 ;
00229         Uint32 white = d->getUint32color(PixRGB<byte>(255, 255, 255));
00230         Uint32 yellow = d->getUint32color(PixRGB<byte>(255, 255, 0));
00231         Uint32 red = d->getUint32color(PixRGB<byte>(255,0,0));
00232         Uint32 green = d->getUint32color(PixRGB<byte>(0,255,0));
00233         Uint32 blue = d->getUint32color(PixRGB<byte>(0,0,255));
00234         if(rd == 0){
00235                 //let's ask the question
00236                 d->pushEvent("asked "+stringify(word)+":-") ;
00237                 d->displayText("'"+disWord+"'",true,1);
00238                 //this will serve as the panle for showing the buttons
00239                 SDL_Surface* blank =getABlankSurface(d->getWidth()/2 , d->getHeight()/10);
00240                 fillRectangle(blank , white , 0  , 0  , blank->w/5 , blank->h );
00241                 fillRectangle(blank , yellow , (blank->w)/5 ,0   , (blank->w)/5 , blank->h );
00242                 fillRectangle(blank , red , 2*(blank->w)/5 ,0   , (blank->w)/5 , blank->h );
00243                 fillRectangle(blank , green , 3*(blank->w)/5 ,0   , (blank->w)/5 , blank->h );
00244                 fillRectangle(blank , blue , 4*(blank->w)/5 ,0   , (blank->w)/5 , blank->h );
00245                 //this is the offset of buttons panel
00246                 SDL_Rect offset;
00247                 offset.x = (d->getWidth() - blank->w) /2;
00248                 offset.y = (d-> getHeight() - blank->h) /2;
00249                 d->pushEvent("the answer panel is going up");
00250                 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00251                 bool quit = false ;
00252                 SDL_Event event ;
00253                 int mx = 0 ; //the  x location of mouse pointer at click time
00254                 int my = 0 ; //the  y location of mouse pointer at click time
00255 
00256                 //in this block we will wait until left burron is down
00257                 while( quit == false ) {
00258                         while( SDL_PollEvent( &event ) ) {
00259                                 if( event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT
00260                                                                 && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00261                                                                 && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00262                                   ) {
00263                                         quit = true;
00264                                         mx = event.button.x ;
00265                                         my = event.button.y ;
00266                                   }
00267                         }
00268                 }
00269                 //let's save the answer in the logfile!
00270                 d->pushEvent("answered: "+ stringify((mx - offset.x) / ((blank->w)/5)) ) ;
00271                 if((mx - offset.x) / ((blank->w)/5) == (int)color) {
00272                         d->pushEvent("correct answer") ;
00273                 }else{
00274                         d->pushEvent("incorrect answer") ;
00275                 }
00276                 dumpSurface(blank) ;
00277 
00278         }else{
00279                 //let's ask the question
00280                 d->pushEvent("asked -:"+stringify(color)) ;
00281                 SDL_Surface* cblank =getABlankSurface((d->getWidth())/10 , d->getHeight()/10);
00282                 Uint32 cl = 0 ;
00283                 switch(color){
00284                         case 0 : cl = white ;break ;
00285                         case 1 : cl = yellow ; break ;
00286                         case 2 : cl = red ; break ;
00287                         case 3 : cl = green ; break ;
00288                         case 4 : cl = blue ; break ;
00289                 }
00290                 fillRectangle(cblank , cl , 0  , 0  , cblank->w , cblank->h );
00291                 SDL_Rect coffset;
00292                 coffset.x = (d->getWidth() - cblank->w) /2;
00293                 coffset.y = (d-> getHeight() - cblank->h) /6;
00294                 d->displaySDLSurfacePatch(cblank , &coffset,NULL , -2,false, true);
00295                 //d->displayText("what word was written in '"+disColor+"'? ",true,1);
00296                 //this is a panel for the buttons
00297                 SDL_Surface* blank =getABlankSurface(3*(d->getWidth())/4 , d->getHeight()/10);
00298                 //and this is a scrap image for writing lables of the buttons
00299                 Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00300                 textIm.clear(PixRGB<byte>(255, 255, 255));
00301                 writeText(textIm, Point2D<int>(10,10), "white");
00302                 writeText(textIm, Point2D<int>(10,110), "yellow");
00303                 writeText(textIm, Point2D<int>(10,210), "red");
00304                 writeText(textIm, Point2D<int>(10,310), "green");
00305                 writeText(textIm, Point2D<int>(10,410), "blue");
00306                 //now let's make a SDL_Surface out of our scrap image
00307                 SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00308                 //we will cut out different clips from the scrap image
00309                 SDL_Rect clip;
00310                 clip.x = 0 ;
00311                 clip.y = 0 ;
00312                 clip.w = (blank->w)/5 - 2 ;
00313                 clip.h =blank->h ;
00314                 //and apply it to the button panel
00315                 apply_surface(0,0,*surf,*blank,clip);
00316                 clip.y = 100 ;
00317                 apply_surface(clip.w + 2 ,0,*surf,*blank,clip);
00318                 clip.y = 200 ;
00319                 apply_surface(2* (clip.w + 2) ,0,*surf,*blank,clip);
00320                 clip.y = 300 ;
00321                 apply_surface(3* (clip.w + 2) ,0,*surf,*blank,clip);
00322                 clip.y = 400 ;
00323                 apply_surface(4* (clip.w + 2) ,0,*surf,*blank,clip);
00324                 //and this the offset for the button panel
00325                 SDL_Rect offset;
00326                 offset.x = (d->getWidth() - blank->w) /2;
00327                 offset.y = (d-> getHeight() - blank->h) /2;
00328                 d->pushEvent("the answer panel is going up");
00329                 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00330                 bool quit = false ;
00331                 SDL_Event event ;
00332                 int mx = 0 ; //the  x location of mouse pointer at click time
00333                 int my = 0 ; //the  y location of mouse pointer at click time
00334 
00335                 //in this block we will wait until left burron is down
00336                 while( quit == false ) {
00337                         while( SDL_PollEvent( &event ) ) {
00338                                 if( event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT
00339                                                                 && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00340                                                                 && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00341                                   ) {
00342                                         quit = true;
00343                                         mx = event.button.x ;
00344                                         my = event.button.y ;
00345                                   }
00346                         }
00347                 }
00348                 d->pushEvent("answered: "+ stringify((mx - offset.x) / ((blank->w)/5)) ) ;
00349                 if((mx - offset.x) / ((blank->w)/5) == (int)word) {
00350                         d->pushEvent("correct answer") ;
00351                 }else{
00352                         d->pushEvent("incorrect answer") ;
00353                 }
00354                 dumpSurface(blank) ;
00355                 dumpSurface(cblank);
00356                 dumpSurface(surf) ;
00357         }
00358         //cleaning up the questions and answers
00359         while(testMap.size()>0){
00360                 map<uint,uint>::iterator it=testMap.begin() ;
00361                 testMap.erase(it);
00362         }
00363         //we make the mouse pointer disappear again!
00364         d->showCursor(false);
00365 }
00366 
00367 
00368 void scramble(vector<string>& v){
00369         vector<string> tv = vector<string>() ;
00370         while(v.size()>0){
00371                 tv.push_back(v[0]);
00372                 v.erase(v.begin());
00373         }
00374         int i = 0 ;
00375         while(tv.size()>0){
00376                 i = rand()%tv.size() ;
00377                 v.push_back(tv[i]);
00378                 tv.erase(tv.begin()+i);
00379         }
00380 }
00381 //this function is used for the memory task, it takes in two lists of file names, one as the target list and
00382 //the second as test images, then it scramble the aggragated list and displays a random array of images, upon
00383 //click on one image a fram apears around the image and by clicking on the framed image the image is selected
00384 //as subject's choice, the choice and correctness will be logged
00385 bool memoryTest(vector<string>& dil , vector<string>& cil){
00386         d->showCursor(true);
00387         bool flag = false ;
00388         //here we decide what is size of grid of images, number of rows and columns are equal
00389         int sf = (int)sqrt(dil.size()+cil.size()) ;
00390         if((uint)(sf*sf) < dil.size()+cil.size() ) sf++ ;
00391         float sizefactor = 1.0f/(float)sf ;
00392         //fls is the aggregated list of file names
00393         vector<string>* fls = new vector<string>() ;
00394         //let's put everything in fls
00395         for(uint i = 0 ; i < dil.size() ; i++){
00396                 fls->push_back(dil[i]);
00397         }
00398         for(uint i = 0 ; i < cil.size() ; i++){
00399                 fls->push_back(cil[i]);
00400         }
00401 
00402         // and then scramble the list in a random fashion
00403         scramble(*fls) ;
00404         //this surface is used for final display
00405         SDL_Surface* blank = getABlankSurface(d->getWidth(),d->getHeight()) ;
00406         //this surface keeps the original display images in the case that we need to refresh the
00407         //the display with original image this one will be copied to blank
00408         SDL_Surface* oblank =  getABlankSurface(d->getWidth(),d->getHeight()) ;
00409         d->displayText("Time for a memory test!",true, 1);
00410         //cout<<cil.size()<< "  "<<dil.size()<<"  "<<fls->size()<<endl;
00411 
00412         //this surface is used as the progress bar
00413         SDL_Surface* pbar = getABlankSurface((d->getWidth())/2,(d->getHeight())/25);
00414         SDL_Rect pbarOffset = SDL_Rect();
00415         pbarOffset.x = (d->getWidth() - pbar->w )/2 ;
00416         pbarOffset.y = (d->getHeight() - pbar->h)/2 ;
00417         d->displaySDLSurfacePatch(pbar , &pbarOffset,NULL , -2,false, true);
00418 
00419         //cframe is a frame on a transparent background put on top of the las choice of the subject
00420         SDL_Surface* cframe = getABlankSurface((d->getWidth())/sf,(d->getHeight())/sf);
00421         Uint32 color = d->getUint32color(PixRGB<byte>(255, 98 , 25));
00422         drawRectangle(cframe , color , 0 , 0 ,cframe->w -2   , cframe->h -2 , 5) ;
00423         if( cframe != NULL )
00424         {
00425             //Map the color key
00426           Uint32 colorkey = SDL_MapRGB( cframe->format, 0x00, 0x00, 0x00 );
00427 
00428             //Set all pixels of color R 0, G 0, B 0 to be transparent
00429           SDL_SetColorKey( cframe, SDL_SRCCOLORKEY, colorkey );
00430         }
00431 
00432         //Now let's load up the images, resize them and put them in the right place of the display
00433         int c = 0 ;
00434         for(int i = 0 ; i < sf ; i++){
00435                 for(int j = 0 ; j < sf ; j++){
00436                         if((uint)(j*sf + i) < fls->size()){
00437                                 c++ ;
00438                                 //let's load the image
00439                                 SDL_Surface* ts = load_image((*fls)[j*sf + i]);
00440                                 sizefactor = min(((float)(d->getWidth()))/sf/((float)(ts->w)),((float)(d->getHeight()))/sf/((float)(ts->h)));
00441                                 //here we resize the image
00442                                 ts = SDL_Resize(ts,sizefactor,5) ;
00443                                 //cout<<(j*sf + i)<<" " <<(*fls)[j*sf + i]<<endl
00444                                 SDL_Rect* clip = new SDL_Rect() ;
00445                                 clip->x = 0 ;
00446                                 clip->y = 0 ;
00447                                 clip->w = ts->w ;
00448                                 clip->h = ts->h ;
00449                                 SDL_Rect offset;
00450                                 offset.x = i*(d->getWidth())/sf + ((d->getWidth())/sf - ts->w)/2;
00451                                 offset.y = j*(d->getHeight())/sf + ((d->getHeight())/sf - ts->h)/2;
00452 
00453                                 //here we apply the surface patch on both copies of the displaying image
00454                                 apply_surface(offset.x, offset.y,*ts,*blank ,*clip);
00455                                 apply_surface(offset.x, offset.y,*ts,*oblank ,*clip);
00456                                 //let's free up the pointers
00457                                 dumpSurface(ts);
00458                                 delete clip ;
00459                                 //let's draw the progress bar
00460                                 Uint32 color = d->getUint32color(PixRGB<byte>(255, 98 , 25));
00461                                 fillRectangle(pbar,color,0,0,(int)((float)((j*sf + i + 1)*(pbar->w))/(float)(fls->size())) , pbar->h);
00462                                 fillRectangle(pbar,color,0,0,(int)((float)c/float(fls->size())) , pbar->h);
00463                                  d->displaySDLSurfacePatch(pbar  , &pbarOffset,NULL , -2,false, true);
00464                         }
00465 
00466 
00467                 }
00468         }
00469         SDL_FreeSurface( pbar );
00470         //here we are ready for displaying the image so let's ask the subject to continue
00471         d->displayText("Click to start!",true);
00472         SDL_Rect offset;
00473         offset.x = 0;
00474         offset.y = 0;
00475         getMouseEvent() ;
00476         d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00477         uint quit = 0 ;
00478         SDL_Event event ;
00479         int fmx = 0 ;
00480         int fmy = 0 ;
00481         int smx = 0 ;
00482         int smy = 0 ;
00483         int choice1 = 0 ;
00484         int choice2 = 0 ;
00485         //here we interact with the subject in order to get the subject's choice
00486         while( quit != 2 ) {
00487                 SDL_Rect tempClip = SDL_Rect();
00488                 tempClip.x = 0 ; tempClip.y=0 ;
00489                 tempClip.w = 10 ; tempClip.h = 10;
00490 
00491                 while( SDL_PollEvent( &event ) ) {
00492 
00493 
00494                   if( event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT
00495                       && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00496                       && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00497                       && quit == 1
00498                     ) {
00499                         smx = event.button.x ;
00500                         smy = event.button.y ;
00501                         choice2 = (int)(sf*(smx-offset.x)/(d->getWidth())) + sf*(int)(sf*(smy-offset.y)/(d->getHeight())) ;
00502                         if(choice1 == choice2){
00503                                 if((uint)choice1 < fls->size()){
00504                                         quit = 2 ;
00505                                         d->pushEvent("memory test choice : "+(*fls)[choice1]);
00506 
00507                                         for(uint f = 0 ; f < dil.size() ; f++){
00508                                                 if((*fls)[choice1].compare(dil[f])==0) {
00509                                                         flag = true ;
00510                                                         break ;
00511                                                 }
00512                                         }
00513 
00514                                         if (flag==true){
00515                                                 d->pushEvent("memory test result : correct" );
00516                                         }else{
00517                                                 d->pushEvent("memory test result : incorrect" );
00518                                         }
00519 
00520                                 }else{
00521                                         quit = 3 ;
00522                                         SDL_Rect* clip = new SDL_Rect() ;
00523                                         SDL_Rect* tof = new SDL_Rect ;
00524                                         tof->x = 0 ; tof->y=0 ;
00525                                         SDL_BlitSurface( oblank, NULL, blank, tof );
00526                                         clip = 0 ;
00527                                         tof=0;
00528                                         d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00529 
00530                                 }
00531 
00532                         }else{
00533                                 quit = 3 ;
00534                                 SDL_Rect* clip = new SDL_Rect() ;
00535                                 clip->x = 0 ;
00536                                 clip->y = 0 ;
00537                                 clip->w = d->getWidth() ;
00538                                 clip->h = d->getHeight() ;
00539                                 SDL_Rect* tof = new SDL_Rect ;
00540                                 tof->x = 0 ; tof->y=0 ;
00541                                 SDL_BlitSurface( oblank, NULL, blank, tof );
00542                                 clip = 0 ;
00543                                 tof=0;
00544                                 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00545                                 }
00546                         }
00547 
00548                         if( event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT
00549                                                  && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00550                                                  && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00551                                                  && quit == 0
00552                           ) {
00553                                 SDL_Rect* clip = new SDL_Rect() ;
00554                                 clip->x = 0 ;
00555                                 clip->y = 0 ;
00556                                 clip->w = oblank->w ;
00557                                 clip->h = oblank->h ;
00558                                 SDL_Rect* tof = new SDL_Rect ;
00559                                 tof->x = 0 ; tof->y=0 ;
00560                                 SDL_BlitSurface( oblank, NULL, blank, tof );
00561                                 clip = 0 ;
00562                                 tof=0;
00563                                 quit = 1;
00564                                 fmx = event.button.x ;
00565                                 fmy = event.button.y ;
00566                                 int i = sf*(fmx-offset.x)/(d->getWidth()) ;
00567                                 int j = sf*(fmy-offset.y)/(d->getHeight());
00568                                 choice1 = (int)(sf*(fmx-offset.x)/(d->getWidth())) + sf*(int)(sf*(fmy-offset.y)/(d->getHeight())) ;
00569                                 tempClip.x =  i*(d->getWidth())/sf; tempClip.y= j*(d->getHeight())/sf;tempClip.w=(d->getWidth())/sf;tempClip.h=(d->getHeight())/sf;
00570                                 SDL_BlitSurface(cframe,NULL,blank,&tempClip) ;
00571                                 d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00572                           }
00573 
00574                         if(quit==3) quit=0 ;
00575 
00576                 }
00577         }
00578 
00579         if(oblank != NULL)
00580         SDL_FreeSurface( oblank );
00581         if(blank != NULL)
00582         SDL_FreeSurface( blank );
00583         SDL_FreeSurface( cframe );
00584         fls = 0 ;
00585         d->clearScreen();
00586         return flag ;
00587 }
00588 void firstTask(const uint l){
00589         Uint32 green = d->getUint32color(PixRGB<byte>(0, 255, 0));
00590         Uint32 blue = d->getUint32color(PixRGB<byte>(0, 0, 255));
00591         Uint32 red = d->getUint32color(PixRGB<byte>(255,0,0));
00592         Uint32 color = 0 ;
00593         int c = 0 ;
00594         SDL_Rect offset;
00595         d->clearScreen() ;
00596         //Give the offsets to the rectangle
00597         SDL_Surface* blankSurface = getABlankSurface(d->getWidth(),d->getHeight()) ;
00598         offset.x = (d->getWidth() - blankSurface->w) /2;
00599         offset.y = (d-> getHeight() - blankSurface->h) /2;
00600         for (uint i = 0 ; i < l ; i++){
00601                 c = rand()%3 ;
00602                 switch(c){
00603                         case 0 : color = red ;break;
00604                         case 1 : color = green ; break ;
00605                         case 2 : color = blue ; break ;
00606                 }
00607 
00608                 fillQuadricRadiant(blankSurface,color,rand()%(blankSurface->w -100 ) + 50 ,rand()%(blankSurface->h -100)+50,20) ;
00609                 d->displaySDLSurfacePatch(blankSurface , &offset,NULL , -2,false, true);
00610                 d->waitFrames(10);
00611         }
00612         dumpSurface(blankSurface) ;
00613 }
00614 
00615 //displays 0 or 1 in a random place on the screen
00616 void finalTask(const int rndBase = 2 , const uint delay = 10 ){
00617         int confNum = rand() % rndBase ;
00618         d->pushEvent(std::string("confirmation number : ")+stringify(confNum));
00619         //let's display  the number in a random place
00620         d->displayText(stringify(confNum),true,-2);
00621         d->waitFrames(delay);
00622         d->clearScreen();
00623         d->pushEvent(std::string("asking for confirmation number"));
00624         d->displayText(std::string("what was the number ? "),true,1);
00625         //we need the subject be able to interact with the mouse
00626         d->showCursor(true);
00627         SDL_Surface* blank =getABlankSurface((d->getWidth())/2 , d->getHeight()/10);
00628         //we make a scrap image to write down the numbers on
00629         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00630         textIm.clear(PixRGB<byte>(255, 255, 255));
00631         //here we write the numbers
00632         for(int i = 0 ; i < rndBase ; i ++){
00633                 writeText(textIm, Point2D<int>((blank->w)/(2*rndBase) -2,10+100*i), stringify(i).c_str());
00634         }
00635         //and here we make a blittabl surface out of that
00636         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00637         //and take out differnt clips out of that
00638         SDL_Rect clip;
00639         clip.x = 0 ;
00640         clip.w = (blank->w)/rndBase - 2 ;
00641         clip.h =blank->h ;
00642         for(int i = 0 ; i < rndBase ; i++){
00643                 clip.y = i*100 ;
00644                 apply_surface(i*(clip.w + 2),0,*surf,*blank,clip);
00645         }
00646 
00647         SDL_Rect offset;
00648         offset.x = (d->getWidth() - blank->w) /2;
00649         offset.y = (d-> getHeight() - blank->h) /2;
00650         d->pushEvent("the button panel is going up");
00651         d->displaySDLSurfacePatch(blank , &offset,NULL , -2,false, true);
00652 
00653         bool quit = false ;
00654         SDL_Event event ;
00655         int mx = 0 ;
00656         int my = 0 ;
00657         while( quit == false ) {
00658                 while( SDL_PollEvent( &event ) ) {
00659                         if( event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT
00660                                                  && event.button.x > offset.x && event.button.x <= offset.x + blank->w
00661                                                  && event.button.y > offset.y && event.button.y <= offset.y + blank->h
00662                           ) {
00663                                 quit = true;
00664                                 mx = event.button.x ;
00665                                 my = event.button.y ;
00666                           }
00667                 }
00668         }
00669 
00670         d->pushEvent("confirmed: " + stringify((mx - offset.x) / ((blank->w)/rndBase))) ;
00671         if((mx - offset.x) / ((blank->w)/rndBase) == (int)confNum) {
00672                 d->pushEvent("correct confirmation") ;
00673         }else{
00674                 d->pushEvent("incorrect confirmation") ;
00675         }
00676 
00677         dumpSurface(blank);
00678         dumpSurface(surf) ;
00679         d->showCursor(false);
00680 
00681 }
00682 
00683 
00684 void getARandomScoop(vector<string> mainlist , vector<string>& targetlist , int s){
00685   //cleaning up the target list
00686   if(targetlist.size()>0) {
00687     while( targetlist.size()!=0 ){
00688       targetlist.erase(targetlist.begin()) ;
00689     }
00690   }
00691  //let's duplicate the mainlist and make a temporary vector
00692   LINFO("scoop1");
00693   vector<string> tv = vector<string>() ;
00694   for(uint i = 0 ; i < mainlist.size() ; i++){
00695     tv.push_back(mainlist[i]);
00696   }
00697 
00698   for(int i = 0 ; i < s ; i++){
00699         int index = rand()%tv.size() ;
00700         targetlist.push_back(tv[index]);
00701         tv.erase(tv.begin());
00702   }
00703   string st = stringify(targetlist.size());
00704   LINFO(st.c_str());
00705 }
00706 
00707 
00708 
00709 int addArgument(const string st,const string delim="="){
00710         int i = st.find(delim) ;
00711         argMap[st.substr(0,i)] = st.substr(i+1);
00712 
00713         return 0 ;
00714 }
00715 
00716 std::string getArgumentValue(string arg){
00717         return argMap[arg] ;
00718 }
00719 
00720 std::string getUsageComment(){
00721 
00722         string com = string("\nlist of arguments : \n");
00723 
00724         com += "\nconf-num=[2..10] (random numbers in confirmation task) {default=2} \n" ;
00725         com += "\nconf-delay=[>1] (the delay in showing the confirmation number) {default=10}\n";
00726         com += "\ndelay-interval=[>1]:[>1] (the interval for random delay after stroop task) {default=10}\n";
00727         com += "\nfixation-blink=[y/n] (show the blink for fixation after stroop task or no) {defaule y}\n";
00728         com += "\nimage-dir=[path to image directory] (needed for mode 2 and 3) {default=60:160} \n"  ;
00729         com += "\nextra-image-dir=[path to extra images directory](needed for lineup memory test)";
00730         com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00731         com += "\nstroop-display-delay=[>1] (number of frames to display the stroop word){default=60}\n";
00732         com += "\nmemo=[a_string_without_white_space]\n";
00733         com += "\nmode=[1..5] (1 for stroop test only, 2 for stroop test + image display + digit memorizetion"
00734                         ", 3 for image display only, 4 for stroop test + image display + image memorizetion, "
00735                         "5 for image display + image memorization ) {default=1}\n";
00736         com += "\nstroop-size=[1..5](number of words in the stroop task){default=3} \n" ;
00737         com += "\nsubject=[subject_name] \n" ;
00738         com += "\ntest-rounds=[>1] (needed for mode1) {default=5}\n";
00739 
00740 
00741         return com ;
00742 }
00743 
00744 
00745 extern "C" int main(const int argc, char** argv)
00746 {
00747 
00748           MYLOGVERB = LOG_INFO;  // suppress debug messages
00749         //let's push the initial value for the parameters
00750         argMap["mode"] = "1" ;
00751         argMap["logfile"]="psycho-stroop-concurrent.psy" ;
00752         argMap["conf-number"] = "2" ;
00753         argMap["stroop-size"]="3" ;
00754         argMap["image-dir"]="..";
00755         argMap["extra-image-dir"] = ".." ;
00756         argMap["conf-delay"]="10" ;
00757         argMap["test-rounds"]="5";
00758         argMap["stroop-display-delay"] = "60" ;
00759         argMap["delay-interval"]="60:160" ;
00760         argMap["subject"]="" ;
00761         argMap["memo"]="" ;
00762         argMap["fixation-blink"]="y" ;
00763         argMap["lineup-size"]="4";
00764         argMap["image-memory-stack"]="4";
00765 
00766         manager.addSubComponent(d);
00767         nub::soft_ref<EventLog> el(new EventLog(manager));
00768         manager.addSubComponent(el);
00769         //*nub::soft_ref<EyeTrackerConfigurator>
00770         //*                etc(new EyeTrackerConfigurator(manager));
00771           //*manager.addSubComponent(etc);
00772 
00773         if (manager.parseCommandLine(argc, argv,
00774             "at least one argument needed", 1, -1)==false){
00775                     LINFO(getUsageComment().c_str());
00776                         return(1);
00777             }
00778 
00779         for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00780                 addArgument(manager.getExtraArg(i),std::string("=")) ;
00781         }
00782 
00783         manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00784         manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00785           // hook our various babies up and do post-command-line configs:
00786         //*nub::soft_ref<EyeTracker> et = etc->getET();
00787         //*d->setEyeTracker(et);
00788         d->setEventLog(el);
00789          //*et->setEventLog(el);
00790 
00791 
00792   // let's get all our ModelComponent instances started:
00793           manager.start();
00794         for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00795   // let's display an ISCAN calibration grid:
00796           d->clearScreen();
00797           d->displayISCANcalib();
00798           d->waitForKey();
00799 
00800   // let's do an eye tracker calibration:
00801           d->displayText("<SPACE> to calibrate; other key to skip");
00802           int c = d->waitForKey();
00803           if (c == ' ') d->displayEyeTrackerCalibration(3,5);
00804 
00805           d->clearScreen();
00806           d->displayText("<SPACE> for random play; other key for ordered");
00807           c = d->waitForKey();
00808 
00809         int mode = atoi(argMap["mode"].c_str()) ;
00810 
00811         if(mode == 1){
00812                 string::size_type position = argMap["delay-interval"].find(":");
00813                 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00814                 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00815                 int numOfTests = atoi(argMap["test-rounds"].c_str()) ;
00816                 int stroopSize = atoi(argMap["stroop-size"].c_str()) ;
00817                 //int confNum = atoi(argMap["conf-number"].c_str()) ;
00818                 //int confDelay = atoi(argMap["conf-delay"].c_str()) ;
00819                 int stroopDelay = atoi(argMap["stroop-display-delay"].c_str());
00820                 for(int i = 0 ; i < numOfTests ; i++){
00821                         d->pushEvent("**************************************") ;
00822                         d->showCursor(true);
00823                         d->displayText("click one of the  mouse buttons to start!");
00824                         getMouseEvent() ;
00825                         d->showCursor(false);
00826                         colorStroopTask(stroopSize,stroopDelay);
00827                         d->waitFrames((rand()%(maxDel - minDel)) +minDel );
00828                         //finalTask(confNum,confDelay) ;
00829                         d->clearScreen() ;
00830                         colorStroopQuiz();
00831                 }
00832         }
00833 
00834         if(mode == 2 ){
00835                 string::size_type position = argMap["delay-interval"].find(":");
00836                 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00837                 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00838                 string dir = argMap["image-dir"];
00839                 vector<string> files = vector<string>();
00840                 getdir(dir,files);
00841                 int stroopSize = atoi(argMap["stroop-size"].c_str()) ;
00842                 int confNum = atoi(argMap["conf-number"].c_str()) ;
00843                 int confDelay = atoi(argMap["conf-delay"].c_str()) ;
00844                 int stroopDelay = atoi(argMap["stroop-display-delay"].c_str());
00845 
00846                 while(files.size()>0){
00847                         int imageIndex = rand()%files.size() ;
00848                         SDL_Surface *surf = load_image(files[imageIndex]);
00849                         float r1 = (float)d->getWidth()/(float)surf->w ;
00850                         float r2 = (float)d->getHeight() / (float)surf->h ;
00851                         surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00852                         SDL_Rect offset;
00853                         offset.x = (d->getWidth() - surf->w) /2;
00854                         offset.y = (d-> getHeight() - surf->h) /2;
00855                         d->pushEvent("**************************************") ;
00856                         d->showCursor(true);
00857                         d->displayText("click a mouse button to start!");
00858                         getMouseEvent() ;
00859                         d->showCursor(false);
00860                         colorStroopTask(stroopSize,stroopDelay);
00861                         d->clearScreen() ;
00862                         d->waitNextRequestedVsync(false, true);
00863                         d->pushEvent(std::string("===== Showing image: ") +
00864                                            files[imageIndex] + " =====");
00865 
00866                         // start the eye tracker:
00867                         //*et->track(true);
00868                               //blink the fixation:
00869                         if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink();
00870 
00871                         d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00872                         d->waitFrames((rand()%(maxDel-minDel)) +minDel );
00873                         dumpSurface(surf);
00874                         // stop the eye tracker:
00875                         usleep(50000);
00876                              //*et->track(false);
00877                         //see if the subject was looking at the screen!
00878                         finalTask(confNum,confDelay) ;
00879                         d->clearScreen() ;
00880                         //now quiz time!
00881                         colorStroopQuiz();
00882                         d->clearScreen() ;
00883                         files.erase(files.begin()+imageIndex);
00884                 }
00885         }
00886 
00887         if(mode == 3){
00888                 string::size_type position = argMap["delay-interval"].find(":");
00889                 int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00890                 int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00891                 string dir = argMap["image-dir"];
00892                 vector<string> files = vector<string>();
00893                 getdir(dir,files);
00894                 int c = 0 ;
00895 
00896                 while(files.size()>0){
00897                         c++ ;
00898                         int imageIndex = rand()%files.size() ;
00899                         //this block turned out to be buggy! so I decided to switch to working with SDL_Surface instead
00900                         //Image< PixRGB<byte> > image =
00901                                         //Raster::ReadRGB(files[imageIndex]);
00902 
00903                         //SDL_Surface *surf = d->makeBlittableSurface(image, true);
00904                         SDL_Surface *surf = load_image(files[imageIndex]);
00905                         float r1 = (float)d->getWidth()/(float)surf->w ;
00906                         float r2 = (float)d->getHeight() / (float)surf->h ;
00907                         surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00908                         SDL_Rect offset;
00909                         offset.x = (d->getWidth() - surf->w) /2;
00910                         offset.y = (d-> getHeight() - surf->h) /2;
00911                         d->waitFrames(45);
00912                         d->waitNextRequestedVsync(false, true);
00913                         d->pushEvent(std::string("===== Showing image: ") +
00914                                            files[imageIndex] + " =====");
00915 
00916                         // start the eye tracker:
00917                         //*et->track(true);
00918                               //blink the fixation:
00919                         if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink();
00920 
00921                         d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00922                         d->waitFrames((rand()%(maxDel-minDel)) +minDel );
00923                         dumpSurface(surf);
00924                         // stop the eye tracker:
00925                         usleep(50000);
00926                              //*et->track(false);
00927                         d->clearScreen() ;
00928                         files.erase(files.begin()+imageIndex);
00929                 }
00930 
00931         }
00932         if(mode==5){
00933           //let's read the parameters related to this part
00934           string::size_type position = argMap["delay-interval"].find(":");
00935           int minDel = atoi(argMap["delay-interval"].substr(0,position).c_str()) ;
00936           int maxDel = atoi(argMap["delay-interval"].substr(position+1).c_str()) ;
00937           vector<string> files = vector<string>();
00938           vector<string> extras = vector<string>();
00939           vector<string> memoryStack = vector<string>();
00940           string dir = argMap["image-dir"];
00941           getdir(dir,files);
00942           dir = argMap["extra-image-dir"];
00943           getdir(dir,extras);
00944           int stroopSize = atoi(argMap["stroop-size"].c_str()) ;
00945           int stroopDelay = atoi(argMap["stroop-display-delay"].c_str());
00946           int lineupSize = atoi(argMap["lineup-size"].c_str()) ;
00947           int stackSize = atoi(argMap["image-memory-stack"].c_str());
00948           while(files.size()>0){
00949             int imageIndex = rand()%files.size() ;
00950             SDL_Surface *surf = load_image(files[imageIndex]);
00951             float r1 = (float)d->getWidth()/(float)surf->w ;
00952             float r2 = (float)d->getHeight() / (float)surf->h ;
00953             surf = SDL_Resize(surf ,min(r1,r2) , 5 );
00954             SDL_Rect offset;
00955             offset.x = (d->getWidth() - surf->w) /2;
00956             offset.y = (d-> getHeight() - surf->h) /2;
00957             d->pushEvent("**************************************") ;
00958             d->showCursor(true);
00959             d->displayText("click a mouse button to start!");
00960             getMouseEvent() ;
00961             d->showCursor(false);
00962             colorStroopTask(stroopSize,stroopDelay);
00963             d->clearScreen() ;
00964             d->waitNextRequestedVsync(false, true);
00965             d->pushEvent(std::string("===== Showing image: ") +
00966                 files[imageIndex] + " =====");
00967 
00968                         // start the eye tracker:
00969                         //*et->track(true);
00970                         //blink the fixation:
00971             if(argMap["fixation-blink"].compare("y")==0) d->displayFixationBlink();
00972 
00973             d->displaySDLSurfacePatch(surf , &offset,NULL , -2,false, true);
00974             d->waitFrames((rand()%(maxDel-minDel)) +minDel );
00975             dumpSurface(surf);
00976                         // stop the eye tracker:
00977             usleep(50000);
00978                         //*et->track(false);
00979             d->clearScreen() ;
00980                         //now quiz time!
00981             colorStroopQuiz();
00982             d->clearScreen() ;
00983             memoryStack.push_back(files[imageIndex]);
00984 
00985             if(memoryStack.size()%stackSize == 0 && memoryStack.size()!=0){
00986 
00987               while( memoryStack.size() != 0 ){
00988                 vector<string> imVector = vector<string>();
00989                 imVector.push_back(memoryStack[0]);
00990                 vector<string> distractorsVector =  vector<string>() ;
00991                 memoryStack.erase(memoryStack.begin());
00992                 vector<string> tv = vector<string>() ;
00993                 for(uint i = 0 ; i < extras.size() ; i++){
00994                         tv.push_back(extras[i]);
00995                 }
00996 
00997                 for(int i = 0 ; i < lineupSize -1 ; i++){
00998                         int index = rand()%tv.size() ;
00999                         distractorsVector.push_back(tv[index]);
01000                         tv.erase(tv.begin());
01001                 }
01002 
01003                 //getARandomScoop(extras,distractorsVector,lineupSize -1 ) ;
01004                 string st = stringify(distractorsVector.size());
01005                 LINFO(st.c_str()) ;
01006                 memoryTest(imVector , distractorsVector);
01007                 //delete distractorsVector;
01008               }
01009             }
01010 
01011             files.erase(files.begin()+imageIndex);
01012           }
01013 
01014         }
01015 
01016         if(mode==6){
01017 
01018         }
01019           d->clearScreen();
01020           d->displayText("Experiment complete. Thank you!");
01021           d->waitForKey();
01022         //getEvent();
01023           // stop all our ModelComponents
01024           manager.stop();
01025 
01026           // all done!
01027           return 0;
01028 }
01029 
01030 #endif // INVT_HAVE_LIBSDL_IMAGE
01031 
Generated on Sun May 8 08:04:11 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3