psycho-sorting-eccentricity.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/psycho-sorting-eccentricity.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/psycho-sorting-eccentricity.C $
00035 // $Id: psycho-sorting-cost.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 <SDL/SDL_mixer.h>
00059 #include <stdio.h>
00060 #include <stdlib.h>
00061 #include <sstream>
00062 #include <time.h>
00063 #include "Image/DrawOps.H"
00064 #include "GameBoard/resize.h"
00065 #include <iostream>
00066 #include <fstream>
00067 #include <set>
00068 #include <algorithm>
00069 #include <ctime>
00070 
00071 #ifndef INVT_HAVE_LIBSDL_IMAGE
00072 #include <cstdio>
00073 int main()
00074 {
00075         fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00076         return 1;
00077 }
00078 
00079 #else
00080 
00081 
00082 
00083 using namespace std;
00084 
00085 // ######################################################################
00086 
00087 ModelManager manager("Psycho-sorting-eccentricity");
00088 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00089 map<uint,uint> testMap ;
00090 map<string,string> argMap ;
00091 map<string,vector<SDL_Rect*>*> clipsmap;
00092 
00093 //////////////////////////////////////////////
00094 // a functionf for stringigying things
00095 //////////////////////////////////////////////
00096 template <class T> std::string stringify(T i)
00097 {
00098         ostringstream o ;
00099         o << i ;
00100         return o.str();
00101 }
00102 
00103 
00104 double getAvarage(vector<long> v){
00105         double f = 0.0 ;
00106         for( uint i = 0 ; i <  v.size() ; i++ ){
00107                 f += v[i] ;
00108         }
00109         if (v.size()!=0) return f/v.size() ;
00110         return -1 ;
00111 }
00112 
00113 double getVariance(vector<long> v){
00114         double m = getAvarage(v);
00115         double var = 0.0 ;
00116         for( uint i = 0 ; i < v.size(); i++ ){
00117                 var += (v[i]-m)*(v[i]-m) ;
00118         }
00119         if (v.size()!=0) return var/v.size() ;
00120         return -1 ;
00121 }
00122 
00123 bool itIsInThere(int x , vector<int> bag){
00124         for( uint i=0 ; i < bag.size(); i++ ){
00125                 if(x == bag[i]) return true ;
00126         }
00127         return false ;
00128 }
00129 
00130 
00131 string get34012(string s){
00132         string t = "";
00133         t = s.substr(3,1)+s.substr(4,1)+s.substr(0,1)+s.substr(1,1)+s.substr(2,1);
00134         return t ;
00135 }
00136 
00137 string get21043(string s){
00138         string t = "";
00139         t = s.substr(2,1)+s.substr(1,1)+s.substr(0,1)+s.substr(4,1)+s.substr(3,1);
00140         return t ;
00141 }
00142 
00143 string get41230(string s){
00144         string t = "";
00145         t = s.substr(4,1)+s.substr(1,1)+s.substr(2,1)+s.substr(3,1)+s.substr(0,1);
00146         return t ;
00147 }
00148 
00149 string get03214(string s){
00150         string t = "";
00151         t = s.substr(0,1)+s.substr(3,1)+s.substr(2,1)+s.substr(1,1)+s.substr(4,1);
00152         return t ;
00153 }
00154 
00155 string get42130(string s){
00156         string t="";
00157         t = s.substr(4,1)+s.substr(2,1)+s.substr(1,1)+s.substr(3,1)+s.substr(0,1);
00158         return t ;
00159 }
00160 
00161 
00162 string get03124(string s){
00163         string t = "" ;
00164         t = s.substr(0,1)+s.substr(3,1)+s.substr(1,1)+s.substr(2,1)+s.substr(4,1);
00165         return t ;
00166 }
00167 
00168 
00169 string get2013(string s){
00170         string t = "" ;
00171         t = s.substr(2,1)+s.substr(0,1)+s.substr(1,1)+s.substr(3,1);
00172         return t ;
00173 }
00174 
00175 string get3201(string s){
00176         string t = "" ;
00177         t = s.substr(3,1)+s.substr(2,1)+s.substr(0,1)+s.substr(1,1);
00178         return t ;
00179 }
00180 
00181 string get3120(string s){
00182         string t = "" ;
00183         t = s.substr(3,1)+s.substr(1,1)+s.substr(2,1)+s.substr(0,1);
00184         return t ;
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //// gets a string as the argument and returns a string composed of
00189 //// characters of the first string sorted in the ascending order
00190 ///////////////////////////////////////////////////////////////////
00191 string ascSort(string st)
00192 {
00193         string res = "" ;
00194         vector<string> v = vector<string>();
00195         for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00196 
00197         std::sort(v.begin(), v.end());
00198 
00199         for ( uint i = 0 ; i < v.size() ; i++ ){
00200                 res += v[i] ;
00201         }
00202         return res;
00203 }
00204 
00205 
00206 
00207 ////////////////////////////////////////////////////////////////////
00208 //// gets a string as the argument and returns a string composed of
00209 //// characters of the first string sorted in the descending order
00210 ///////////////////////////////////////////////////////////////////
00211 string desSort(string st)
00212 {
00213         string res = "" ;
00214         vector<string> v = vector<string>();
00215         for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00216         std::sort(v.begin(), v.end());
00217         std::reverse(v.begin(), v.end());
00218         for ( uint i = 0 ; i < v.size() ; i++ ){
00219                 res += v[i] ;
00220         }
00221         return res;
00222 }
00223 
00224 
00225 
00226 
00227 
00228 ////////////////////////////////////////////////////////
00229 ///// simply generates a sequence of digits with given alphabet with length of l with given threshold, if the given threshold is not achieved the best answer with
00230 //highest metric value in 1000000 times try will be returned
00231 ////////////////////////////////////////////////////////
00232 
00233 string getARandomString(uint l, string alphabet="0123456789"){
00234 
00235         string test = string("") ;
00236         test = "" ;
00237         string tp = string("") ;
00238         vector<int> pickedones = vector<int>() ;
00239         for(uint i = 0 ; i < l ; i++){
00240                 int nd;
00241                 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00242                 pickedones.push_back(nd);
00243                 tp = alphabet.substr(nd,1) ;
00244                 test += tp ;
00245         }
00246 
00247         return test ;
00248 }
00249 
00250 ///////////////////////////////////////////////////////
00251 //this function is not called in this program, but it generates a random string and it will show it in
00252 //a random place on the screen.
00253 //////////////////////////////////////////////////////
00254 string digitMemorizationTask(uint l, string alphabet="0123456789" , int displayFrame = 10  ){
00255         d->clearScreen() ;
00256         vector<int> pickedones = vector<int>() ;
00257         string test = string("") ;
00258         string tp = string("") ;
00259         for(uint i = 0 ; i < l ; i++){
00260                 int nd;
00261                 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00262                 pickedones.push_back(nd);
00263                 tp = alphabet.substr(nd,1) ;
00264                 test += tp ;
00265         }
00266         d->displayText(test,true,0) ;
00267         d->waitFrames(displayFrame) ;
00268         d->clearScreen() ;
00269         return test ;
00270 }
00271 
00272 
00273 ////////////////////////////////////////////////////////
00274 ///////this will change the order of elements in a vector to a random order
00275 ////////////////////////////////////////////////////////
00276 void scramble(vector<string>& v){
00277         vector<string> tv = vector<string>() ;
00278         while(v.size()>0){
00279                 tv.push_back(v[0]);
00280                 v.erase(v.begin());
00281         }
00282         int i = 0 ;
00283         while(tv.size()>0){
00284                 i = rand()%tv.size() ;
00285                 v.push_back(tv[i]);
00286                 tv.erase(tv.begin()+i);
00287         }
00288 }
00289 
00290 void scramble(vector<int>& v){
00291         vector<int> tv = vector<int>() ;
00292         while(v.size()>0){
00293                 tv.push_back(v[0]);
00294                 v.erase(v.begin());
00295         }
00296         int i = 0 ;
00297         while(tv.size()>0){
00298                 i = rand()%tv.size() ;
00299                 v.push_back(tv[i]);
00300                 tv.erase(tv.begin()+i);
00301         }
00302 }
00303 
00304 ////////////////////////////////////////////////////////////////
00305 ////This is our button factory
00306 ////////////////////////////////////////////////////////////////
00307 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){
00308         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00309         textIm.clear(bgcolor);
00310         writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00311         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00312         Uint32 bc = d->getUint32color(bordercolor);
00313         drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00314         SDL_Surface* blank =getABlankSurface(size.i , size.j);
00315         SDL_Rect clip;
00316         clip.x = 0 ;
00317         clip.y = 0 ;
00318         clip.w = size.i ;
00319         clip.h = size.j ;
00320         apply_surface(0,0,*surf,*blank,clip);
00321         dumpSurface(surf) ;
00322         return blank ;
00323 }
00324 
00325 ////////////////////////////////////////////////////////////////////////
00326 ////This is the function for creating the keypad, in fact it generates
00327 ////12 buttons and associates the actions to the region for each button
00328 ////////////////////////////////////////////////////////////////////////
00329 
00330 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00331         SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00332         SDL_Rect clip;
00333         clip.x=0;
00334         clip.y=0;
00335         int numofrows = alphabet.size()/3 +1;
00336         if(alphabet.size()%3 != 0 ) numofrows++ ;
00337         int numofcolumns = 3 ;
00338         clip.w= pad->w / numofcolumns ;
00339         clip.h = pad->h / numofrows ;
00340 
00341   //keys for 1 to 9
00342         for( int i = 0 ; i < numofrows*3 ; i++){
00343                 SDL_Surface* but ;
00344                 if((uint)i < alphabet.size()){
00345                         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);
00346                 }else{
00347                         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);
00348                 }
00349 
00350                 SDL_Rect cl ;
00351                 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00352                 cl.w = clip.w ;
00353                 cl.h = clip.h ;
00354                 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00355                 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00356                 dumpSurface(but);
00357         }
00358         SDL_Rect cl1 ;
00359         cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00360         cl1.w = clip.w ;
00361         cl1.h = clip.h ;
00362         buttmap["!"] = cl1 ;
00363         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);
00364         apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00365         dumpSurface(but);
00366         SDL_Rect cl2 ;
00367         cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00368         cl2.w = clip.w ;
00369         cl2.h = clip.h ;
00370         buttmap[" "] = cl2 ;
00371         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);
00372         apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00373         dumpSurface(but);
00374         SDL_Rect cl3 ;
00375         cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00376         cl3.w = clip.w ;
00377         cl3.h = clip.h ;
00378         buttmap["*"] = cl3 ;
00379         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);
00380         apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00381         dumpSurface(but);
00382         return pad ;
00383 }
00384 
00385 
00386 
00387 
00388 ///////////////////////////////////////////////////////////////////////////
00389 /////this function listens to mouse clicks and then finds the region of the screen
00390 /////associated with the action, buttmap is the map of the region, offset is the offset of
00391 /////buttons
00392 ///////////////////////////////////////////////////////////////////////////
00393 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00394         int quit = 0 ;
00395         string s ;
00396         SDL_Event event ;
00397         while( quit!=2 ){
00398                 while( SDL_PollEvent( &event ) ) {
00399                         if(event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT ){
00400                                 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00401                                         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) {
00402                                                 quit = 2 ;
00403                                                 s = it->first ;
00404                                                 break;
00405                                         }
00406 
00407                                 }
00408                         }
00409 
00410                 }
00411         }
00412         return s ;
00413 
00414 }
00415 
00416 
00417 ////////////////////////////////////////////////////
00418 ////This function creates a virtual keypad, creates a map of buttons
00419 ////and their representation area and listens to the button press and at
00420 ////the end returns the keyed digits
00421 ////////////////////////////////////////////////////
00422 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00423         d->showCursor(true) ;
00424         //let's creat a map to map actions to regions of the screen, each region is represented as an SDL_Rect
00425         map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00426         //now let's get the keypad surface while we get the actions map to regions
00427         SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00428         //this will be the offset of displaying the keypad on the screen
00429         SDL_Rect offset ;
00430         offset.x = (d->getWidth() - keypad->w) /2;
00431         offset.y = (d-> getHeight() - keypad->h) /2;
00432         //now let's display the keypad
00433         d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00434         //this will hold the final string keyed be the subject
00435         string p = string("") ;
00436         //this is a temporary string holding the last action related to the pressed key
00437         string tp = string("");
00438         //now let's record subject's key press
00439         while( tp.compare("*")!=0 ){
00440                 //this button is actually the display for the current string
00441                 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) ;
00442                 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00443                 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00444                 //now let's listen to button events
00445                 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00446                 dumpSurface(dp) ;
00447                 if(tp.compare("!")==0 && p.size()>=0 ) {
00448                         if (p.size()>0) p = p.substr(0,p.size()-1) ;
00449                 }else{
00450                         if(p.size() < maxl && tp.compare("*")!=0) {
00451                                 p +=tp ;
00452                         }
00453 
00454                 }
00455 
00456         }
00457         buttmap = 0 ;
00458         dumpSurface(keypad) ;
00459         d->clearScreen() ;
00460         return p ;
00461 
00462 }
00463 
00464 
00465 
00466 ///////////////////////////////////////////////////////////////
00467 //////gets the test string, answer and the mode and identifies if
00468 //////the answer matches the thing it should be, mode=0 checks if
00469 //////if the answer and test string simply the same, mode=1 matches
00470 //////the answer against the ascending sorted string of the test string
00471 //////mode=2 compares the answer against the descending sorted of
00472 //////the test string
00473 ///////////////////////////////////////////////////////////////
00474 bool isAnswerCorrect(string test , string answer , int mode){
00475 
00476         if(mode == 0 && answer.compare(test)==0) return true ;
00477 
00478         if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00479 
00480         if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00481 
00482         return false;
00483 }
00484 
00485 
00486 
00487 int addArgument(const string st,const string delim="="){
00488         int i = st.find(delim) ;
00489         argMap[st.substr(0,i)] = st.substr(i+1);
00490 
00491         return 0 ;
00492 }
00493 
00494 std::string getArgumentValue(string arg){
00495         return argMap[arg] ;
00496 }
00497 
00498 std::string getUsageComment(){
00499 
00500         string com = string("\nlist of arguments : \n");
00501 
00502         com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00503         com += "\nmemo=[a_string_without_white_space]\n";
00504         com += "\nstring-size=[>0](the size of string){default=5} \n";
00505         com += "\nsubject=[subject_name] \n" ;
00506         com += "\nnum-of-sorting-trials=[>1](number of trials){default=10}\n";
00507         com += "\nnum-of-mem-trials=[>1](number of trials){default=10}\n";
00508         com += "\ndigit-onset=[>1] (number of frames that the string will remain onset ){default=10}\n";
00509         com += "\nalphabet=[a string of characters](a string of characters){default=0123456789}\n";
00510         com += "\nmode=[1,2,3,4](1 for displaying the whole number, 2 for random display , 3 for linear flashing disply , 4 for linear reverse flashing){default=1}\n";
00511         com += "\ncue-wait-frames=[<0](number of frames to show the cue){default=0}\n";
00512         com += "\nmask=[y/n](whether present a mask after presentation, n for no, y  for yes ){default=n}\n" ;
00513         com += "\nmask-onset-frames=[<0](number of frames that mask will be onset){default=0}\n";
00514         com += "\nwhite-space=[>0](the distance between digits in display){default=20}\n" ;
00515         com += "\ncue-type=[a/v](a for audio v for visual){default=v}\n";
00516         com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00517 
00518         return com ;
00519 }
00520 
00521 
00522 void displayWholeNumber(string s , int onsetTime , int wsd){
00523         int x = (d->getWidth()-s.size()*wsd)/2 ;
00524         int y = (d->getHeight())/2 -10;
00525         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00526         textIm.clear(PixRGB<byte>(128,128,128));
00527         for( uint k = 0 ; k < s.size() ; k++ ){
00528                // d->displayText(s.substr(k,1),Point2D<int>(x,y+k*10),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00529                 writeText(textIm, Point2D<int>(x+k*wsd,y),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00530         }
00531         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00532         SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00533         d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00534         dumpSurface(surf);
00535         d->waitFrames(onsetTime);
00536         d->clearScreen() ;
00537 }
00538 
00539 void displayWholeNumberVertically(string s , int onsetTime , int wsd){
00540         int x = (d->getWidth())/2 ;
00541         int y = (d->getHeight()-s.size()*wsd)/2 ;
00542         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00543         textIm.clear(PixRGB<byte>(128,128,128));
00544         for( uint k = 0 ; k < s.size() ; k++ ){
00545                // d->displayText(s.substr(k,1),Point2D<int>(x,y+k*10),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00546                 writeText(textIm, Point2D<int>(x,y+k*wsd),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00547         }
00548         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00549         SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00550         d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00551         dumpSurface(surf);
00552         d->waitFrames(onsetTime);
00553         d->clearScreen() ;
00554 }
00555 
00556 void displayRandom(string s , int onsetTime){
00557         for( uint k = 0 ; k < s.size() ; k++ ){
00558                 int x = 9*d->getWidth()/20 + rand()%(d->getWidth()/10);
00559                 int y = 9*d->getHeight()/20 + rand()%(d->getHeight()/10) ;
00560                 d->displayText(s.substr(k,1),Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00561                 d->waitFrames(onsetTime);
00562                 d->clearScreen() ;
00563         }
00564 }
00565 
00566 void displayLinear(string s , int onsetTime){
00567         int x = (d->getWidth()-s.size()*10)/2 ;
00568         int y = d->getHeight()/2 - 10;
00569         for( uint k = 0 ; k < s.size() ; k++ ){
00570                 d->displayText(s.substr(k,1),Point2D<int>(x+k*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00571                 d->waitFrames(onsetTime);
00572                 d->clearScreen() ;
00573         }
00574 }
00575 
00576 void displayLinearReverse(string s , int onsetTime){
00577         int x = (d->getWidth()-s.size()*10)/2 ;
00578         int y = d->getHeight()/2 - 10;
00579         for( uint k = 0 ; k < s.size() ; k++ ){
00580                 d->displayText(s.substr(k,1),Point2D<int>(x+(s.size()-k)*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00581                 d->waitFrames(onsetTime);
00582                 d->clearScreen() ;
00583         }
00584 }
00585 void displayLinearRandom(string s , int onsetTime){
00586         int x = (d->getWidth()-s.size()*10)/2 ;
00587         int y = d->getHeight()/2 - 10;
00588         for( uint k = 0 ; k < s.size() ; k++ ){
00589                 d->displayText(s.substr(k,1),Point2D<int>(x+ (random()%s.size())*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00590                 d->waitFrames(onsetTime);
00591                 d->clearScreen() ;
00592         }
00593 }
00594 
00595 void displayLinearRandomVertically(string s , int onsetTime){
00596         int x = (d->getWidth())/2 ;
00597         int y = (d->getHeight()-s.size()*10)/2 - 10;
00598         for( uint k = 0 ; k < s.size() ; k++ ){
00599                 d->displayText(s.substr(k,1),Point2D<int>(x, (random()%s.size())*10+y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00600                 d->waitFrames(onsetTime);
00601                 d->clearScreen() ;
00602         }
00603 }
00604 
00605 void displayLinearRandomNoRepeating(string s , int onsetTime){
00606         int x = (d->getWidth()-s.size()*10)/2 ;
00607         int y = d->getHeight()/2 - 10;
00608         for( uint k = 0 ; k < s.size() ; k++ ){
00609                 d->displayText(s.substr(k,1),Point2D<int>(x+ (random()%s.size())*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00610                 d->waitFrames(onsetTime);
00611                 d->clearScreen() ;
00612         }
00613 }
00614 
00615 //and this is the function which creates and displays a mask of randomly positioned numbers
00616 void showMask(int frames, string alphabet="0123456789"){
00617         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00618         PixRGB<byte> bgcolor = PixRGB<byte>(128,128,128);
00619         PixRGB<byte> txtcolor = PixRGB<byte>(0,0,0);
00620         textIm.clear(bgcolor);
00621         for(int i = 0 ;  i < 800 ; i++)
00622                 writeText(textIm, Point2D<int>((int)random()%(d->getWidth()),(int)random()%(d->getHeight())),alphabet.substr(random()%(int)alphabet.size(),1).c_str(),txtcolor,bgcolor);
00623         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00624         SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00625         d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00626         d->waitFrames(frames) ;
00627         d->clearScreen();
00628         dumpSurface(surf) ;
00629 }
00630 
00631 extern "C" int main(const int argc, char** argv)
00632 {
00633 
00634         MYLOGVERB = LOG_INFO;  // suppress debug messages
00635         //let's push the initial value for the parameters
00636         argMap["experiment"]="working memory single task - sorting";
00637         argMap["logfile"]="psycho-sorting-const.psy" ;
00638         argMap["string-size"]="4" ;
00639         argMap["subject"]="" ;
00640         argMap["memo"]="" ;
00641         argMap["digit-onset"]="10" ;
00642         argMap["alphabet"]="bcdfghjkmprvx";
00643         argMap["mode"]="1" ;
00644         argMap["cue-wait-frames"]="0" ;
00645         argMap["mask"]="n" ;
00646         argMap["cue-onset-frames"] = "3" ;
00647         argMap["white-space"] = "20" ;
00648         argMap["cue-type"] = "v" ;
00649         argMap["sound-dir"]="..";
00650         argMap["num-of-trials"] = "27" ;
00651         manager.addSubComponent(d);
00652         nub::soft_ref<EventLog> el(new EventLog(manager));
00653         manager.addSubComponent(el);
00654         d->setEventLog(el);
00655         nub::soft_ref<EyeTrackerConfigurator>
00656                         etc(new EyeTrackerConfigurator(manager));
00657           manager.addSubComponent(etc);
00658 
00659         if (manager.parseCommandLine(argc, argv,
00660             "at least one argument needed", 1, -1)==false){
00661                     cout<<getUsageComment()<<endl;
00662                     return(1);
00663             }
00664 
00665             for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00666                     addArgument(manager.getExtraArg(i),std::string("=")) ;
00667             }
00668 
00669             manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00670         manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00671         nub::soft_ref<EyeTracker> eyet = etc->getET();
00672         d->setEyeTracker(eyet);
00673         eyet->setEventLog(el);
00674 
00675 
00676   // let's get all our ModelComponent instances started:
00677             manager.start();
00678             for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00679   // let's display an ISCAN calibration grid:
00680             d->clearScreen();
00681             d->displayISCANcalib();
00682             d->waitForMouseClick();
00683             d->displayText("Here the experiment starts! click to start!");
00684             d->waitForMouseClick();
00685             d->clearScreen();
00686         //let's see in what mode the user like to run the program
00687             int mode = atoi(argMap["mode"].c_str());
00688             vector<long> correctAnswersTiming;
00689             vector<long> incorrectAnswersTiming;
00690             vector<long> allTiming ;
00691             int correctMemory = 0 ;
00692             int incorrectMemory = 0 ;
00693             int stringSize = atoi(argMap["string-size"].c_str());
00694             int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00695             int cue_wait_frames = atoi(argMap["cue-wait-frames"].c_str()) ;
00696             int mask_onset_frames = atoi(argMap["mask-onset-frames"].c_str()) ;
00697             int white_sapece_distance = atoi(argMap["white-space"].c_str());
00698             int num_of_trials = atoi(argMap["num-of-trials"].c_str()) ;
00699             vector<string>* testVector = new vector<string>();
00700             string se1="cfhk"; testVector->push_back(get3201(se1));testVector->push_back(get2013(se1));testVector->push_back(get3120(se1));
00701             string se2="bdhj"; testVector->push_back(get3201(se2));testVector->push_back(get2013(se2));testVector->push_back(get3120(se2));
00702             string se3="dfgk"; testVector->push_back(get3201(se3));testVector->push_back(get2013(se3));testVector->push_back(get3120(se3));
00703             string le1="dkrv"; testVector->push_back(get3201(le1));testVector->push_back(get2013(le1));testVector->push_back(get3120(le1));
00704             string le2="bjmx"; testVector->push_back(get3201(le2));testVector->push_back(get2013(le2));testVector->push_back(get3120(le2));
00705             string le3="ckpv"; testVector->push_back(get3201(le3));testVector->push_back(get2013(le3));testVector->push_back(get3120(le3));
00706             scramble(*testVector);
00707             //let's do calibration
00708             d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00709             int cl = d->waitForMouseClick();
00710             if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00711             d->clearScreen() ;
00712 
00713             Mix_Music* recallCueMusic = NULL;
00714             Mix_Music* sortCueMusic = NULL;
00715             if(argMap["cue-type"].compare("a")==0){
00716                      //now let's open the audio channel
00717                     if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00718                             LINFO( "did not open the mix-audio") ;
00719                             return -1 ;
00720                     }
00721 
00722                         string str = argMap["sound-dir"]+"/recall.wav" ;
00723                         recallCueMusic = Mix_LoadMUS(str.c_str());
00724                         str = argMap["sound-dir"]+"/sort.wav" ;
00725                         sortCueMusic = Mix_LoadMUS(str.c_str());
00726             }
00727             vector<int>* taskVector = new vector<int>();
00728             for(int i = 0 ; i < 18 ; i++) taskVector->push_back(1);
00729             for(int i = 0 ; i < 9 ; i++)  taskVector->push_back(0);
00730             scramble(*taskVector);
00731             int testCounter = 0 ;
00732             for( int r = 0 ; (int)r < min((int)taskVector->size(),num_of_trials) ; r++ ){
00733                             
00734                             int task = taskVector->at(r) ;
00735                             d->pushEvent("**************************************") ;
00736                             d->showCursor(true);
00737                             d->displayText("click one of the  mouse buttons to start!");
00738                             d->waitForMouseClick() ;
00739                             d->showCursor(false) ;
00740                             string testString ;
00741                             
00742                             switch( task ){
00743                                 case 0 : testString = getARandomString(stringSize, argMap["alphabet"]);break ;
00744                                 case 1 : testString = testVector->at(testCounter);testCounter++;break ;
00745                             }
00746                             d->clearScreen() ;
00747                             d->displayFixationBlink();
00748                             switch( mode ){
00749                                     case 1 : displayWholeNumber(testString,onsetDel,white_sapece_distance);break ;
00750                                     case 2 : displayRandom(testString,onsetDel) ; break ;
00751                                     case 3 : displayLinear(testString,onsetDel) ; break ;
00752                                     case 4 : displayLinearRandom(testString,onsetDel) ; break ;
00753                                     case 5 : displayLinearReverse(testString,onsetDel) ; break ;
00754                                     case 6 : displayLinearRandomVertically(testString,onsetDel) ; break ;
00755                                     case 7 : displayWholeNumberVertically(testString,onsetDel,white_sapece_distance) ; break ;
00756                             }
00757                             if(argMap["mask"].compare("y")==0) showMask(mask_onset_frames,argMap["alphabet"]);
00758                             if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00759                             d->displayFixation() ;
00760                             if(argMap["cue-type"].compare("v")==0){
00761                                     d->displayRedDotFixation();
00762                             }else{
00763                                 if(task == 0){if( Mix_PlayMusic( recallCueMusic, 0 ) == -1 ) { return 1; }
00764                                     while( Mix_PlayingMusic() == 1 ){}
00765                                 }else{
00766                                     if( Mix_PlayMusic( sortCueMusic, 0 ) == -1 ) { return 1; }
00767                                     while( Mix_PlayingMusic() == 1 ){}
00768                                 }
00769 
00770                             }
00771 
00772                             d->clearScreen() ;
00773                             string imst ;
00774                             if(task!=0){
00775                                 imst= "===== Showing image: def_"+stringify(task)+"_"+stringify(testCounter)+"_"+testString+".png =====";
00776                                 d->pushEvent("the sequence for operation is : "+testString) ;
00777                                 d->pushEvent(imst);
00778                                 eyet->track(true);
00779                                 d->waitForMouseClick();
00780                                 eyet->track(false);
00781                                 d->pushEvent("task ends") ;
00782                                 string  answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size());
00783                                 d->pushEvent("subject keyed : "+answer);
00784                                 if(answer.compare(ascSort(testString))==0){
00785                                     d->pushEvent("answer was correct");
00786                                     d->displayText(":)");
00787                                 }else{
00788                                     d->pushEvent("answer was incorrect");
00789                                     d->displayText(":(");
00790                                 }
00791                             }else{
00792                                  string  answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size());
00793                                 d->pushEvent("subject keyed : "+answer);
00794                                 if(answer.compare(testString)==0){
00795                                     d->pushEvent("recall was correct");
00796                                     d->displayText(":)");
00797                                     correctMemory++ ;
00798                                 }else{
00799                                     d->pushEvent("recall was incorrect");
00800                                     d->displayText(")");
00801                                     incorrectMemory++ ;
00802                                 }
00803                             }
00804 
00805             }
00806             d->pushEvent("number of correct memory recall : "+ stringify(correctMemory)) ;
00807             d->pushEvent("number of incorrect memory recall : "+ stringify(incorrectMemory)) ;
00808             d->clearScreen();
00809             d->displayText("Experiment complete. Thank you!");
00810             d->waitForMouseClick();
00811             taskVector = 0 ;
00812           // stop all our ModelComponents
00813             manager.stop();
00814 
00815 
00816           // all done!
00817             return 0;
00818 }
00819 
00820 #endif // INVT_HAVE_LIBSDL_IMAGE
00821 
Generated on Sun May 8 08:04:13 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3