psycho-sorting-cost-audio.C

00001 /*!@file AppPsycho/psycho-sorting-cost.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-cost-audio.C $
00035 // $Id: psycho-sorting-cost-audio.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-Concurrent-Digit");
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,2)+s.substr(2,1)+s.substr(4,1);
00165         return t ;
00166 }
00167 ////////////////////////////////////////////////////////////////////
00168 //// gets a string as the argument and returns a string composed of
00169 //// characters of the first string sorted in the ascending order
00170 ///////////////////////////////////////////////////////////////////
00171 string ascSort(string st)
00172 {
00173         string res = "" ;
00174         vector<string> v = vector<string>();
00175         for(uint i = 0 ; i < st.size() ; i++) v.push_back(st.substr(i,1)) ;
00176 
00177         std::sort(v.begin(), v.end());
00178 
00179         for ( uint i = 0 ; i < v.size() ; i++ ){
00180                 res += v[i] ;
00181         }
00182         return res;
00183 }
00184 
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 descending order
00190 ///////////////////////////////////////////////////////////////////
00191 string desSort(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         std::sort(v.begin(), v.end());
00197         std::reverse(v.begin(), v.end());
00198         for ( uint i = 0 ; i < v.size() ; i++ ){
00199                 res += v[i] ;
00200         }
00201         return res;
00202 }
00203 
00204 
00205 
00206 
00207 
00208 ////////////////////////////////////////////////////////
00209 ///// 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
00210 //highest metric value in 1000000 times try will be returned
00211 ////////////////////////////////////////////////////////
00212 
00213 string getARandomString(uint l, string alphabet="0123456789"){
00214 
00215         string test = string("") ;
00216         test = "" ;
00217         string tp = string("") ;
00218         vector<int> pickedones = vector<int>() ;
00219         for(uint i = 0 ; i < l ; i++){
00220                 int nd;
00221                 do{ nd= rand()% alphabet.size() ; }while(itIsInThere(nd,pickedones) && pickedones.size() <= alphabet.size()) ;
00222                 pickedones.push_back(nd);
00223                 tp = alphabet.substr(nd,1) ;
00224                 test += tp ;
00225         }
00226 
00227         return test ;
00228 }
00229 
00230 ///////////////////////////////////////////////////////
00231 //this function is not called in this program, but it generates a random string and it will show it in
00232 //a random place on the screen.
00233 //////////////////////////////////////////////////////
00234 string digitMemorizationTask(uint l, string alphabet="0123456789" , int displayFrame = 10  ){
00235         d->clearScreen() ;
00236         vector<int> pickedones = vector<int>() ;
00237         string test = string("") ;
00238         string tp = string("") ;
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         d->displayText(test,true,0) ;
00247         d->waitFrames(displayFrame) ;
00248         d->clearScreen() ;
00249         return test ;
00250 }
00251 
00252 
00253 ////////////////////////////////////////////////////////
00254 ///////this will change the order of elements in a vector to a random order
00255 ////////////////////////////////////////////////////////
00256 void scramble(vector<string>& v){
00257         vector<string> tv = vector<string>() ;
00258         while(v.size()>0){
00259                 tv.push_back(v[0]);
00260                 v.erase(v.begin());
00261         }
00262         int i = 0 ;
00263         while(tv.size()>0){
00264                 i = rand()%tv.size() ;
00265                 v.push_back(tv[i]);
00266                 tv.erase(tv.begin()+i);
00267         }
00268 }
00269 
00270 void scramble(vector<int>& v){
00271         vector<int> tv = vector<int>() ;
00272         while(v.size()>0){
00273                 tv.push_back(v[0]);
00274                 v.erase(v.begin());
00275         }
00276         int i = 0 ;
00277         while(tv.size()>0){
00278                 i = rand()%tv.size() ;
00279                 v.push_back(tv[i]);
00280                 tv.erase(tv.begin()+i);
00281         }
00282 }
00283 
00284 ////////////////////////////////////////////////////////////////
00285 ////This is our button factory
00286 ////////////////////////////////////////////////////////////////
00287 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){
00288         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00289         textIm.clear(bgcolor);
00290         writeText(textIm, Point2D<int>((size.i - label.length()*10)/2,(size.j-20) /2),label.c_str(),txtcolor,bgcolor);
00291         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00292         Uint32 bc = d->getUint32color(bordercolor);
00293         drawRectangle(surf,bc,0,0,size.i -1,size.j -1 ,border);
00294         SDL_Surface* blank =getABlankSurface(size.i , size.j);
00295         SDL_Rect clip;
00296         clip.x = 0 ;
00297         clip.y = 0 ;
00298         clip.w = size.i ;
00299         clip.h = size.j ;
00300         apply_surface(0,0,*surf,*blank,clip);
00301         dumpSurface(surf) ;
00302         return blank ;
00303 }
00304 
00305 ////////////////////////////////////////////////////////////////////////
00306 ////This is the function for creating the keypad, in fact it generates
00307 ////12 buttons and associates the actions to the region for each button
00308 ////////////////////////////////////////////////////////////////////////
00309 
00310 SDL_Surface* getKeyPad(string alphabet,map<string , SDL_Rect>& buttmap){
00311         SDL_Surface* pad= getABlankSurface(d->getWidth()/4,d->getHeight()/3);
00312         SDL_Rect clip;
00313         clip.x=0;
00314         clip.y=0;
00315         int numofrows = alphabet.size()/3 +1;
00316         if(alphabet.size()%3 != 0 ) numofrows++ ;
00317         int numofcolumns = 3 ;
00318         clip.w= pad->w / numofcolumns ;
00319         clip.h = pad->h / numofrows ;
00320 
00321   //keys for 1 to 9
00322         for( int i = 0 ; i < numofrows*3 ; i++){
00323                 SDL_Surface* but ;
00324                 if((uint)i < alphabet.size()){
00325                         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);
00326                 }else{
00327                         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);
00328                 }
00329 
00330                 SDL_Rect cl ;
00331                 cl.x = ((i)%numofcolumns)*(pad->w)/numofcolumns ; cl.y= ((i)/numofcolumns)*((pad->h)/numofrows) ;
00332                 cl.w = clip.w ;
00333                 cl.h = clip.h ;
00334                 apply_surface( cl.x , cl.y ,*but,*pad,clip);
00335                 if((uint)i < alphabet.size()) buttmap[alphabet.substr(i,1)] = cl ;
00336                 dumpSurface(but);
00337         }
00338         SDL_Rect cl1 ;
00339         cl1.x = 0 ; cl1.y= (numofrows-1)*((pad->h)/numofrows) ;
00340         cl1.w = clip.w ;
00341         cl1.h = clip.h ;
00342         buttmap["!"] = cl1 ;
00343         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);
00344         apply_surface(0, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00345         dumpSurface(but);
00346         SDL_Rect cl2 ;
00347         cl2.x = (pad->w)/numofcolumns ; cl2.y= (numofrows-1)*((pad->h)/numofrows) ;
00348         cl2.w = clip.w ;
00349         cl2.h = clip.h ;
00350         buttmap[" "] = cl2 ;
00351         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);
00352         apply_surface((pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00353         dumpSurface(but);
00354         SDL_Rect cl3 ;
00355         cl3.x = 2*(pad->w)/numofcolumns ; cl3.y= (numofrows-1)*((pad->h)/numofrows) ;
00356         cl3.w = clip.w ;
00357         cl3.h = clip.h ;
00358         buttmap["*"] = cl3 ;
00359         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);
00360         apply_surface(2*(pad->w)/numofcolumns, (numofrows-1)*((pad->h)/numofrows),*but,*pad,clip);
00361         dumpSurface(but);
00362         return pad ;
00363 }
00364 
00365 
00366 
00367 
00368 ///////////////////////////////////////////////////////////////////////////
00369 /////this function listens to mouse clicks and then finds the region of the screen
00370 /////associated with the action, buttmap is the map of the region, offset is the offset of
00371 /////buttons
00372 ///////////////////////////////////////////////////////////////////////////
00373 string getPressedButtonCommand(map<string , SDL_Rect>& buttmap,Point2D<int> offset=Point2D<int>(0,0)){
00374         int quit = 0 ;
00375         string s ;
00376         SDL_Event event ;
00377         while( quit!=2 ){
00378                 while( SDL_PollEvent( &event ) ) {
00379                         if(event.type == SDL_MOUSEBUTTONDOWN  && event.button.button == SDL_BUTTON_LEFT ){
00380                                 for( map<string , SDL_Rect>::iterator it = buttmap.begin() ; it!=buttmap.end() ; ++it){
00381                                         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) {
00382                                                 quit = 2 ;
00383                                                 s = it->first ;
00384                                                 break;
00385                                         }
00386 
00387                                 }
00388                         }
00389 
00390                 }
00391         }
00392         return s ;
00393 
00394 }
00395 
00396 
00397 ////////////////////////////////////////////////////
00398 ////This function creates a virtual keypad, creates a map of buttons
00399 ////and their representation area and listens to the button press and at
00400 ////the end returns the keyed digits
00401 ////////////////////////////////////////////////////
00402 string getDigitSequenceFromSubject(string alphabet="0123456789" , uint maxl = 7 ){
00403         d->showCursor(true) ;
00404         //let's creat a map to map actions to regions of the screen, each region is represented as an SDL_Rect
00405         map<string , SDL_Rect>* buttmap = new map<string , SDL_Rect>();
00406         //now let's get the keypad surface while we get the actions map to regions
00407         SDL_Surface * keypad = getKeyPad(alphabet,*buttmap);
00408         //this will be the offset of displaying the keypad on the screen
00409         SDL_Rect offset ;
00410         offset.x = (d->getWidth() - keypad->w) /2;
00411         offset.y = (d-> getHeight() - keypad->h) /2;
00412         //now let's display the keypad
00413         d->displaySDLSurfacePatch(keypad , &offset,NULL , -2,false, true);
00414         //this will hold the final string keyed be the subject
00415         string p = string("") ;
00416         //this is a temporary string holding the last action related to the pressed key
00417         string tp = string("");
00418         //now let's record subject's key press
00419         while( tp.compare("*")!=0 ){
00420                 //this button is actually the display for the current string
00421                 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) ;
00422                 SDL_Rect offs ; offs.x = (d->getWidth() - dp->w) /2 ; offs.y = d->getHeight()/6 ;
00423                 d->displaySDLSurfacePatch(dp , &offs , NULL , -2 , false ,true ) ;
00424                 //now let's listen to button events
00425                 tp = getPressedButtonCommand(*buttmap,Point2D<int>(offset.x,offset.y)) ;
00426                 dumpSurface(dp) ;
00427                 if(tp.compare("!")==0 && p.size()>=0 ) {
00428                         if (p.size()>0) p = p.substr(0,p.size()-1) ;
00429                 }else{
00430                         if(p.size() < maxl && tp.compare("*")!=0) {
00431                                 p +=tp ;
00432                         }
00433 
00434                 }
00435 
00436         }
00437         buttmap = 0 ;
00438         dumpSurface(keypad) ;
00439         d->clearScreen() ;
00440         return p ;
00441 
00442 }
00443 
00444 
00445 
00446 ///////////////////////////////////////////////////////////////
00447 //////gets the test string, answer and the mode and identifies if
00448 //////the answer matches the thing it should be, mode=0 checks if
00449 //////if the answer and test string simply the same, mode=1 matches
00450 //////the answer against the ascending sorted string of the test string
00451 //////mode=2 compares the answer against the descending sorted of
00452 //////the test string
00453 ///////////////////////////////////////////////////////////////
00454 bool isAnswerCorrect(string test , string answer , int mode){
00455 
00456         if(mode == 0 && answer.compare(test)==0) return true ;
00457 
00458         if(mode == 1 && answer.compare(ascSort(test))==0) return true ;
00459 
00460         if(mode == 2 && answer.compare(desSort(test))==0) return true ;
00461 
00462         return false;
00463 }
00464 
00465 
00466 
00467 int addArgument(const string st,const string delim="="){
00468         int i = st.find(delim) ;
00469         argMap[st.substr(0,i)] = st.substr(i+1);
00470 
00471         return 0 ;
00472 }
00473 
00474 std::string getArgumentValue(string arg){
00475         return argMap[arg] ;
00476 }
00477 
00478 std::string getUsageComment(){
00479 
00480         string com = string("\nlist of arguments : \n");
00481 
00482         com += "\nlogfile=[logfilename.psy] {default = psycho-stroop-concurrent.psy}\n" ;
00483         com += "\nmemo=[a_string_without_white_space]\n";
00484         com += "\nstring-size=[>0](the size of string){default=5} \n";
00485         com += "\nsubject=[subject_name] \n" ;
00486         com += "\nnum-of-sorting-trials=[>1](number of trials){default=10}\n";
00487         com += "\nnum-of-mem-trials=[>1](number of trials){default=10}\n";
00488         com += "\ndigit-onset=[>1] (number of frames that the string will remain onset ){default=10}\n";
00489         com += "\nalphabet=[a string of characters](a string of characters){default=0123456789}\n";
00490         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";
00491         com += "\ncue-wait-frames=[<0](number of frames to show the cue){default=0}\n";
00492         com += "\nmask=[y/n](whether present a mask after presentation, n for no, y  for yes ){default=n}\n" ;
00493         com += "\nmask-onset-frames=[<0](number of frames that mask will be onset){default=0}\n";
00494         com += "\nwhite-space=[>0](the distance between digits in display){default=20}\n" ;
00495         com += "\ncue-type=[a/v](a for audio v for visual){default=v}\n";
00496         com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00497 
00498         return com ;
00499 }
00500 
00501 
00502 void displayWholeNumber(string s , int onsetTime , int wsd){
00503         int x = (d->getWidth()-s.size()*wsd)/2 ;
00504         int y = (d->getHeight())/2 -10;
00505         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00506         textIm.clear(PixRGB<byte>(128,128,128));
00507         for( uint k = 0 ; k < s.size() ; k++ ){
00508                // d->displayText(s.substr(k,1),Point2D<int>(x,y+k*10),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00509                 writeText(textIm, Point2D<int>(x+k*wsd,y),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00510         }
00511         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00512         SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00513         d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00514         dumpSurface(surf);
00515         d->waitFrames(onsetTime);
00516         d->clearScreen() ;
00517 }
00518 
00519 void displayWholeNumberVertically(string s , int onsetTime , int wsd){
00520         int x = (d->getWidth())/2 ;
00521         int y = (d->getHeight()-s.size()*wsd)/2 ;
00522         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00523         textIm.clear(PixRGB<byte>(128,128,128));
00524         for( uint k = 0 ; k < s.size() ; k++ ){
00525                // d->displayText(s.substr(k,1),Point2D<int>(x,y+k*10),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00526                 writeText(textIm, Point2D<int>(x,y+k*wsd),s.substr(k,1).c_str(),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128));
00527         }
00528         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00529         SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00530         d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00531         dumpSurface(surf);
00532         d->waitFrames(onsetTime);
00533         d->clearScreen() ;
00534 }
00535 
00536 void displayRandom(string s , int onsetTime){
00537         for( uint k = 0 ; k < s.size() ; k++ ){
00538                 int x = 9*d->getWidth()/20 + rand()%(d->getWidth()/10);
00539                 int y = 9*d->getHeight()/20 + rand()%(d->getHeight()/10) ;
00540                 d->displayText(s.substr(k,1),Point2D<int>(x,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00541                 d->waitFrames(onsetTime);
00542                 d->clearScreen() ;
00543         }
00544 }
00545 
00546 void displayLinear(string s , int onsetTime){
00547         int x = (d->getWidth()-s.size()*10)/2 ;
00548         int y = d->getHeight()/2 - 10;
00549         for( uint k = 0 ; k < s.size() ; k++ ){
00550                 d->displayText(s.substr(k,1),Point2D<int>(x+k*10,y),PixRGB<byte>(0,0,0),PixRGB<byte>(128,128,128),true) ;
00551                 d->waitFrames(onsetTime);
00552                 d->clearScreen() ;
00553         }
00554 }
00555 
00556 void displayLinearReverse(string s , int onsetTime){
00557         int x = (d->getWidth()-s.size()*10)/2 ;
00558         int y = d->getHeight()/2 - 10;
00559         for( uint k = 0 ; k < s.size() ; k++ ){
00560                 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) ;
00561                 d->waitFrames(onsetTime);
00562                 d->clearScreen() ;
00563         }
00564 }
00565 void displayLinearRandom(string s , int onsetTime){
00566         int x = (d->getWidth()-s.size()*10)/2 ;
00567         int y = d->getHeight()/2 - 10;
00568         for( uint k = 0 ; k < s.size() ; k++ ){
00569                 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) ;
00570                 d->waitFrames(onsetTime);
00571                 d->clearScreen() ;
00572         }
00573 }
00574 
00575 void displayLinearRandomVertically(string s , int onsetTime){
00576         int x = (d->getWidth())/2 ;
00577         int y = (d->getHeight()-s.size()*10)/2 - 10;
00578         for( uint k = 0 ; k < s.size() ; k++ ){
00579                 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) ;
00580                 d->waitFrames(onsetTime);
00581                 d->clearScreen() ;
00582         }
00583 }
00584 
00585 void displayLinearRandomNoRepeating(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 //and this is the function which creates and displays a mask of randomly positioned numbers
00596 void showMask(int frames, string alphabet="0123456789"){
00597         Image<PixRGB<byte> > textIm(d->getWidth(),d->getHeight(),ZEROS);
00598         PixRGB<byte> bgcolor = PixRGB<byte>(128,128,128);
00599         PixRGB<byte> txtcolor = PixRGB<byte>(0,0,0);
00600         textIm.clear(bgcolor);
00601         for(int i = 0 ;  i < 800 ; i++)
00602                 writeText(textIm, Point2D<int>((int)random()%(d->getWidth()),(int)random()%(d->getHeight())),alphabet.substr(random()%(int)alphabet.size(),1).c_str(),txtcolor,bgcolor);
00603         SDL_Surface *surf = d->makeBlittableSurface(textIm , true);
00604         SDL_Rect offs ; offs.x = 0 ; offs.y = 0 ;
00605         d->displaySDLSurfacePatch(surf , &offs , NULL , -2 , false ,true ) ;
00606         d->waitFrames(frames) ;
00607         d->clearScreen();
00608         dumpSurface(surf) ;
00609 }
00610 
00611 
00612 vector<string> getAll_34012(string al="0123456789"){
00613             string tmp;
00614             vector<string> outVector ;
00615             for(int i0=0 ;i0<10 ;i0++ ){
00616                 for( int i1=i0+2;i1<10 ; i1++ ){
00617                     for( int i2=i1+2 ;i2<10 ; i2++){
00618                         for( int i3=i2+1  ; i3 <10 ; i3++ ){
00619                             for( int i4=i3+2; i4 < 10 ; i4++){
00620                                 tmp = al.substr(i3,1)+al.substr(i4,1)+al.substr(i0,1)+al.substr(i1,1)+al.substr(i2,1);
00621                                 outVector.push_back(tmp);
00622                             }
00623                         }
00624                     }
00625                 }
00626             }
00627 return outVector ;
00628         }
00629 
00630 vector<string> getAll_21043(string al="0123456789"){
00631             string tmp;
00632             vector<string> outVector ;
00633             for(int i0=0 ;i0<10 ;i0++ ){
00634                 for( int i1=i0+2;i1<10 ; i1++ ){
00635                     for( int i2=i1+2 ;i2<10 ; i2++){
00636                         for( int i3=i2+1  ; i3 <10 ; i3++ ){
00637                             for( int i4=i3+2; i4 < 10 ; i4++){
00638                                 tmp = al.substr(i2,1)+al.substr(i1,1)+al.substr(i0,1)+al.substr(i4,1)+al.substr(i3,1);
00639                                 outVector.push_back(tmp);
00640                             }
00641                         }
00642                     }
00643                 }
00644             }
00645 return outVector ;
00646         }
00647 vector<string> getAll_41230(string al="0123456789"){
00648             string tmp;
00649             vector<string> outVector ;
00650             for(int i0=0 ;i0<10 ;i0++ ){
00651                 for( int i1=i0+1;i1<10 ; i1++ ){
00652                     for( int i2=i1+2 ;i2<10 ; i2++){
00653                         for( int i3=i2+2  ; i3 <10 ; i3++ ){
00654                             for( int i4=i3+1; i4 < 10 ; i4++){
00655                                 tmp = al.substr(i4,1)+al.substr(i1,1)+al.substr(i2,1)+al.substr(i3,1)+al.substr(i0,1);
00656                                 outVector.push_back(tmp);
00657                             }
00658                         }
00659                     }
00660                 }
00661             }
00662 return outVector ;
00663         }
00664 
00665 vector<string> getAll_03214(string al="0123456789"){
00666             string tmp;
00667             vector<string> outVector ;
00668             for(int i0=0 ;i0<10 ;i0++ ){
00669                 for( int i1=i0+1;i1<10 ; i1++ ){
00670                     for( int i2=i1+2 ;i2<10 ; i2++){
00671                         for( int i3=i2+2  ; i3 <10 ; i3++ ){
00672                             for( int i4=i3+1; i4 < 10 ; i4++){
00673                                 tmp = al.substr(i0,1)+al.substr(i3,1)+al.substr(i2,1)+al.substr(i1,1)+al.substr(i4,1);
00674                                 outVector.push_back(tmp);
00675                             }
00676                         }
00677                     }
00678                 }
00679             }
00680 return outVector ;
00681         }
00682 
00683 extern "C" int main(const int argc, char** argv)
00684 {
00685 
00686         MYLOGVERB = LOG_INFO;  // suppress debug messages
00687         //let's push the initial value for the parameters
00688         argMap["experiment"]="working memory single task - sorting";
00689         argMap["logfile"]="psycho-sorting-const.psy" ;
00690         argMap["string-size"]="5" ;
00691         argMap["subject"]="" ;
00692         argMap["memo"]="" ;
00693         argMap["digit-onset"]="10" ;
00694         argMap["alphabet"]="0123456789";
00695         argMap["mode"]="1" ;
00696         argMap["cue-wait-frames"]="0" ;
00697         argMap["mask"]="n" ;
00698         argMap["cue-onset-frames"] = "3" ;
00699         argMap["white-space"] = "20" ;
00700         argMap["cue-type"] = "v" ;
00701         argMap["sound-dir"]="..";
00702             argMap["num-of-sorting-trials"] = "10" ;
00703         argMap["num-of-mem-trials"] = "10" ;
00704         manager.addSubComponent(d);
00705         nub::soft_ref<EventLog> el(new EventLog(manager));
00706         manager.addSubComponent(el);
00707         d->setEventLog(el);
00708         nub::soft_ref<EyeTrackerConfigurator>
00709                         etc(new EyeTrackerConfigurator(manager));
00710           manager.addSubComponent(etc);
00711 
00712         if (manager.parseCommandLine(argc, argv,
00713             "at least one argument needed", 1, -1)==false){
00714                     cout<<getUsageComment()<<endl;
00715                     return(1);
00716             }
00717 
00718             for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00719                     addArgument(manager.getExtraArg(i),std::string("=")) ;
00720             }
00721 
00722             manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00723         manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00724         nub::soft_ref<EyeTracker> eyet = etc->getET();
00725         d->setEyeTracker(eyet);
00726         eyet->setEventLog(el);
00727 
00728 
00729   // let's get all our ModelComponent instances started:
00730             manager.start();
00731             for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00732   // let's display an ISCAN calibration grid:
00733             d->clearScreen();
00734             d->displayISCANcalib();
00735             d->waitForMouseClick();
00736             d->displayText("Here the experiment starts! click to start!");
00737             d->waitForMouseClick();
00738             d->clearScreen();
00739         //let's see in what mode the user like to run the program
00740             int mode = atoi(argMap["mode"].c_str());
00741             vector<long> correctAnswersTiming;
00742             vector<long> incorrectAnswersTiming;
00743             vector<long> allTiming ;
00744             int correctMemory = 0 ;
00745             int incorrectMemory = 0 ;
00746             int stringSize = atoi(argMap["string-size"].c_str());
00747             int onsetDel = atoi(argMap["digit-onset"].c_str()) ;
00748             int cue_wait_frames = atoi(argMap["cue-wait-frames"].c_str()) ;
00749             int mask_onset_frames = atoi(argMap["mask-onset-frames"].c_str()) ;
00750             int white_sapece_distance = atoi(argMap["white-space"].c_str());
00751                     int num_of_sorting_task = atoi(argMap["num-of-sorting-trials"].c_str()) ;
00752             int num_of_mem_task = atoi(argMap["num-of-mem-trials"].c_str()) ;
00753             string alphabet = argMap["alphabet"];
00754             //let's do calibration
00755             d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00756             int cl = d->waitForMouseClick();
00757             if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00758             d->clearScreen() ;
00759 
00760             map<int,Mix_Music*>  audio_map ;//we will have access to the audios for stimulus presentation using this map
00761                         map<string,int>  charmap ;
00762                         map<int,string>  charinvmap ;
00763             Mix_Music* recallCueMusic = NULL;
00764             Mix_Music* sortCueMusic = NULL;
00765             if(argMap["cue-type"].compare("a")==0){
00766                      //now let's open the audio channel
00767                     if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00768                             LINFO( "did not open the mix-audio") ;
00769                             return -1 ;
00770                     }
00771 
00772                         string str = argMap["sound-dir"]+"/recall.wav" ;
00773                         recallCueMusic = Mix_LoadMUS(str.c_str());
00774                         if(recallCueMusic==NULL) cout<<"not a 16 bit wav file  "<<str<<endl;
00775                         str = argMap["sound-dir"]+"/sort.wav" ;
00776                         sortCueMusic = Mix_LoadMUS(str.c_str());
00777                         if(sortCueMusic==NULL) cout<<"not a 16 bit wav file  "<<str<<endl;
00778                                                 for(uint i = 0; i < alphabet.size() ; i++){
00779                                                         string str = argMap["sound-dir"]+"/"+alphabet.substr(i,1)+".wav";
00780                                                         audio_map[i]=Mix_LoadMUS(str.c_str());
00781                                                         if(audio_map[i]==NULL) cout<<"not a 16 bit wav file  "<<str<<endl;
00782                                                         charmap[alphabet.substr(i,1)]=i;
00783                                                         charinvmap[i]=alphabet.substr(i,1) ;
00784                                                 }
00785             }
00786             vector<int>* taskVector = new vector<int>();
00787             for(int i = 0 ; i < (int)(num_of_sorting_task/4) ; i++) {
00788                     taskVector->push_back(1);
00789                     taskVector->push_back(2);
00790                     taskVector->push_back(3);
00791                     taskVector->push_back(4);
00792                     //taskVector->push_back(5);
00793                     //taskVector->push_back(6)
00794             }
00795             vector<string> _34012 = getAll_34012();
00796             vector<string> _21043 = getAll_21043();
00797             vector<string> _41230 = getAll_41230();
00798             vector<string> _03214 = getAll_03214();
00799             scramble(_34012);
00800             scramble(_21043);
00801             scramble(_41230);
00802             scramble(_03214);
00803             int ind1 = 0 ; int ind2 = 0 ; int ind3 = 0 ;int ind4 = 0 ;
00804             for(int i = 0 ; i < num_of_mem_task ; i++)  taskVector->push_back(0);
00805             scramble(*taskVector);
00806             for( int r = 0 ; (int)r < (int)taskVector->size() ; r++ ){
00807 
00808                             int task = taskVector->at(r) ;
00809                             d->pushEvent("**************************************") ;
00810                             d->showCursor(true);
00811                             d->displayText("click one of the  mouse buttons to start!");
00812                             d->waitForMouseClick() ;
00813                             d->showCursor(false) ;
00814                             string testString ;
00815                             testString = getARandomString(stringSize, argMap["alphabet"]);
00816                             switch( task ){
00817                                 case 1 : testString = _34012.at(ind1);ind1++;break ;
00818                                 case 2 : testString = _21043.at(ind2);ind2++;break ;
00819                                 case 3 : testString = _41230.at(ind3);ind3++;break ;
00820                                 case 4 : testString = _03214.at(ind4);ind4++;break ;
00821                                                                 case 5 : testString = get42130(ascSort(testString));break ;
00822                                                                 case 6 : testString = get03124(ascSort(testString));break ;
00823                             }
00824                             d->clearScreen() ;
00825                             d->displayFixationBlink();
00826                                                         if(argMap["cue-type"].compare("a")==0){
00827                                                                         for(int i = 0 ; i < (int)testString.size(); i++){
00828                                                                                 if( Mix_PlayMusic( audio_map[charmap[testString.substr(i,1)]], 0 ) == -1 ) { return 1; }
00829                                             while( Mix_PlayingMusic() == 1 ){}
00830                                         d->waitFrames(onsetDel);
00831                                                                         }
00832                                                         }else{
00833                             switch( mode ){
00834                                     case 1 : displayWholeNumber(testString,onsetDel,white_sapece_distance);break ;
00835                                     case 2 : displayRandom(testString,onsetDel) ; break ;
00836                                     case 3 : displayLinear(testString,onsetDel) ; break ;
00837                                     case 4 : displayLinearRandom(testString,onsetDel) ; break ;
00838                                     case 5 : displayLinearReverse(testString,onsetDel) ; break ;
00839                                     case 6 : displayLinearRandomVertically(testString,onsetDel) ; break ;
00840                                     case 7 : displayWholeNumberVertically(testString,onsetDel,white_sapece_distance) ; break ;
00841                             }
00842                                                         }
00843                             if(argMap["mask"].compare("y")==0) showMask(mask_onset_frames,argMap["alphabet"]);
00844                             if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00845                             d->displayFixation() ;
00846                             if(argMap["cue-type"].compare("v")==0){
00847                                     d->displayRedDotFixation();
00848                             }else{
00849                                 if(task == 0){if( Mix_PlayMusic( recallCueMusic, 0 ) == -1 ) { return 1; }
00850                                     while( Mix_PlayingMusic() == 1 ){}
00851                                 }else{
00852                                     if( Mix_PlayMusic( sortCueMusic, 0 ) == -1 ) { return 1; }
00853                                     while( Mix_PlayingMusic() == 1 ){}
00854                                 }
00855 
00856                             }
00857 
00858                             d->clearScreen() ;
00859                             string imst ;
00860                             if(task!=0){
00861                                 imst= "===== Showing image: def_"+stringify(task)+"_"+testString+".png =====";
00862                                 d->pushEvent("the sequence for operation is : "+testString) ;
00863                                 d->pushEvent(imst);
00864                                 eyet->track(true);
00865                                 d->waitForMouseClick();
00866                                 eyet->track(false);
00867                                 d->pushEvent("task ends") ;
00868                                 string  answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size());
00869                                 d->pushEvent("subject keyed : "+answer);
00870                                 if(answer.compare(ascSort(testString))==0){
00871                                     d->pushEvent("answer was correct");
00872                                 }else{
00873                                     d->pushEvent("answer was incorrect");
00874                                 }
00875                             }else{
00876                                  string  answer = getDigitSequenceFromSubject(argMap["alphabet"] , testString.size());
00877                                 d->pushEvent("subject keyed : "+answer);
00878                                 if(answer.compare(testString)==0){
00879                                     d->pushEvent("recall was correct");
00880                                     correctMemory++ ;
00881                                 }else{
00882                                     d->pushEvent("recall was incorrect");
00883                                     incorrectMemory++ ;
00884                                 }
00885                             }
00886 
00887             }
00888             d->pushEvent("number of correct memory recall : "+ stringify(correctMemory)) ;
00889             d->pushEvent("number of incorrect memory recall : "+ stringify(incorrectMemory)) ;
00890             d->clearScreen();
00891             d->displayText("Experiment complete. Thank you!");
00892             d->waitForMouseClick();
00893             taskVector = 0 ;
00894           // stop all our ModelComponents
00895             manager.stop();
00896 
00897 
00898           // all done!
00899             return 0;
00900 }
00901 
00902 #endif // INVT_HAVE_LIBSDL_IMAGE
00903 
Generated on Sun May 8 08:04:13 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3