psycho-wm-chunking.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/psycho-wm-chunking.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-wm-chunking.C $
00035 
00036 
00037 #include "Component/ModelManager.H"
00038 #include "Image/Image.H"
00039 #include "Psycho/PsychoDisplay.H"
00040 #include "Psycho/EyeTrackerConfigurator.H"
00041 #include "Psycho/EyeTracker.H"
00042 #include "Psycho/PsychoOpts.H"
00043 #include "Component/EventLog.H"
00044 #include "Component/ComponentOpts.H"
00045 #include "Raster/Raster.H"
00046 #include "Util/MathFunctions.H"
00047 #include "Util/Types.H"
00048 #include "GameBoard/basic-graphics.H"
00049 #include <sys/types.h>
00050 #include <dirent.h>
00051 #include <errno.h>
00052 #include <vector>
00053 #include <string>
00054 #include <iostream>
00055 #include <SDL/SDL.h>
00056 #include <SDL/SDL_image.h>
00057 #include <SDL/SDL_mixer.h>
00058 #include <stdio.h>
00059 #include <stdlib.h>
00060 #include <sstream>
00061 #include <time.h>
00062 #include "Image/DrawOps.H"
00063 #include "GameBoard/resize.h"
00064 #include <iostream>
00065 #include <fstream>
00066 #include <set>
00067 #include <algorithm>
00068 #include <ctime>
00069 
00070 #ifndef INVT_HAVE_LIBSDL_IMAGE
00071 #include <cstdio>
00072 int main()
00073 {
00074         fprintf(stderr, "The SDL_image library must be installed to use this program\n");
00075         return 1;
00076 }
00077 
00078 #else
00079 
00080 
00081 
00082 using namespace std;
00083 
00084 // ######################################################################
00085 
00086 ModelManager manager("psycho-wm-chunking");
00087 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00088 map<uint,uint> testMap ;
00089 map<string,string> argMap ;
00090 map<string,vector<SDL_Rect*>*> clipsmap;
00091 
00092 //////////////////////////////////////////////
00093 // a functionf for stringigying things
00094 //////////////////////////////////////////////
00095 template <class T> std::string stringify(T i)
00096 {
00097         ostringstream o ;
00098         o << i ;
00099         return o.str();
00100 }
00101 
00102 bool itIsInThere(int x , vector<int> bag){
00103         for( uint i=0 ; i < bag.size(); i++ ){
00104                 if(x == bag[i]) return true ;
00105         }
00106         return false ;
00107 }
00108 
00109 
00110 
00111 ////////////////////////////////////////////////////////
00112 ///////this will change the order of elements in a vector to a random order
00113 ////////////////////////////////////////////////////////
00114 void scramble(vector<int>& v){
00115         vector<int> tv = vector<int>() ;
00116         while(v.size()>0){
00117                 tv.push_back(v[0]);
00118                 v.erase(v.begin());
00119         }
00120         int i = 0 ;
00121         while(tv.size()>0){
00122                 i = rand()%tv.size() ;
00123                 v.push_back(tv[i]);
00124                 tv.erase(tv.begin()+i);
00125         }
00126 }
00127 
00128 
00129 
00130 //pushes back the name of wav files in the directory into the given vector
00131 int getdir (string dir, vector<string> &files)
00132 {
00133         DIR *dp;
00134         struct dirent *dirp;
00135         if((dp  = opendir(dir.c_str())) == NULL) {
00136                 cout << "Error(" << errno << ") opening " << dir << endl;
00137                 return errno;
00138         }
00139         string fn = "" ;
00140         size_t found;
00141         string extension = "" ;
00142         while ((dirp = readdir(dp)) != NULL) {
00143                 fn = string(dirp->d_name) ;
00144                 found = fn.find_last_of(".");
00145                 if(found > 0 && found <1000){
00146                         extension = fn.substr(found) ;
00147                         if(extension.compare(".wav")== 0 )
00148                                 files.push_back(dir+"/"+fn);
00149                 }
00150         }
00151         closedir(dp);
00152         return 0;
00153 }
00154 
00155 
00156 
00157 
00158 
00159 
00160 
00161 
00162 int addArgument(const string st,const string delim="="){
00163         int i = st.find(delim) ;
00164         argMap[st.substr(0,i)] = st.substr(i+1);
00165 
00166         return 0 ;
00167 }
00168 
00169 std::string getArgumentValue(string arg){
00170         return argMap[arg] ;
00171 }
00172 
00173 std::vector<int> getDigits(int n , string zs="n" , string rs="n" ){
00174         if(rs.compare("n")==0){
00175                 if(zs.compare("n")==0 && n >9 ) {LINFO( "come on! what do you expect?!") ;  exit(-1) ;}
00176                 if(zs.compare("y")==0 && n >10 ) {LINFO( "come on! what do you expect?!") ; exit(-1) ;}
00177         }
00178         vector<int> digits ;
00179         int dig = 0 ;
00180         while( digits.size() < (uint)n ){
00181                 if(zs.compare("n")==0) {dig = 1+(random()%9);}else{dig = random()%10;}
00182                 if(rs.compare("y")==0){digits.push_back(dig);}else{if(!itIsInThere(dig,digits)) digits.push_back(dig);}
00183         }
00184         return digits ;
00185 }
00186 
00187 std::string getUsageComment(){
00188 
00189         string com = string("\nlist of arguments : \n");
00190 
00191         com += "\nlogfile=[logfilename.psy] {default = psycho-wm-chunking.psy}\n" ;
00192         com += "\nmemo=[a_string_without_white_space]\n";
00193         com += "\nnum-of-digits=[>0](the size of string){default=3} \n";
00194         com += "\nsubject=[subject_name] \n" ;
00195         com += "\nseperate-recall-rounds=[>1] (number of trials including seperate recall task ) {default=2}\n";
00196         com += "\nfirst-to-last-rounds=[>1](number of trials including first to last chunking){default=2}}\n";
00197         com += "\nlast-to-first-rounds=[>1](number of trials including last to firts chunking){default=2}}\n";
00198         com += "\nalphabet=[a string of characters](a string of characters){default=0123456789}\n";
00199         com += "\ncue-wait-frames=[>0](number of frames to show the cue){default=0}\n";
00200         com += "\ncue-onset-frames=[>0](number of frames to show the cue onset){default=10}\n";
00201         com += "\nsound-dir=[path to wav files directory]{default=..}\n";
00202         com += "\ndigit-repeat=[y/n](whether digits can repeat, y for yes , n for no){default=n}\n" ;
00203         com += "\ninclude-zero=[y/n](whether zero be included in the presented digits, y for yes , n for no){default=n}\n";
00204         com += "\ndelay=[>1] (delay in number of frames in which recording happens)\n" ;
00205         return com ;
00206 }
00207 
00208 
00209 extern "C" int main(const int argc, char** argv)
00210 {
00211 
00212         MYLOGVERB = LOG_INFO;  // suppress debug messages
00213         //let's push the initial value for the parameters
00214         argMap["experiment"]="chunking firs to last, chunking last to first and no chunking";
00215         argMap["logfile"]="psycho-wm-chunking.psy" ;
00216         argMap["num-of-digits"]="3" ;
00217         argMap["seperate-recall-rounds"]="2";
00218         argMap["first-to-last-rounds"] = "2" ;
00219         argMap["last-to-first-rounds"] = "2" ;
00220         argMap["subject"]="" ;
00221         argMap["memo"]="" ;
00222         argMap["alphabet"]="0123456789";
00223         argMap["cue-wait-frames"]="0" ;
00224         argMap["cue-onset-frames"] = "10" ;
00225         argMap["sound-dir"]="..";
00226         argMap["include-zero"]="n";
00227         argMap["digit-repeat"]="n" ;
00228         argMap["delay"] = "120" ;
00229 
00230         manager.addSubComponent(d);
00231         nub::soft_ref<EventLog> el(new EventLog(manager));
00232         manager.addSubComponent(el);
00233         d->setEventLog(el);
00234         nub::soft_ref<EyeTrackerConfigurator>
00235                         etc(new EyeTrackerConfigurator(manager));
00236           manager.addSubComponent(etc);
00237 
00238         if (manager.parseCommandLine(argc, argv,
00239             "at least one argument needed", 1, -1)==false){
00240                     cout<<getUsageComment()<<endl;
00241                     return(1);
00242             }
00243 
00244         for(uint i = 0 ; i < manager.numExtraArgs() ; i++){
00245                     addArgument(manager.getExtraArg(i),std::string("=")) ;
00246         }
00247 
00248         manager.setOptionValString(&OPT_EventLogFileName, argMap["logfile"]);
00249         manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00250         nub::soft_ref<EyeTracker> eyet = etc->getET();
00251         d->setEyeTracker(eyet);
00252         eyet->setEventLog(el);
00253 
00254         //now let's open the audio channel
00255          if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00256                     LINFO( "did not open the mix-audio") ;
00257                     return -1 ;
00258             }
00259         //let's load the 10 audio files off the director of audios and put them in a map
00260         map<int,Mix_Music*> audioMap ;
00261         for( int i = 0 ; i < 10 ; i++ ){
00262                 string str = argMap["sound-dir"]+"/"+stringify(i)+".wav" ;
00263                 audioMap[i] = Mix_LoadMUS(str.c_str());
00264         }
00265         int delay = atoi(argMap["delay"].c_str()) ;
00266         int numOfDigits = atoi(argMap["num-of-digits"].c_str());
00267         int cue_onset_frames = atoi(argMap["cue-onset-frames"].c_str()) ;
00268         int cue_wait_frames = atoi(argMap["cue-wait-frames"].c_str()) ;
00269         int num_of_first_task = atoi(argMap["seperate-recall-rounds"].c_str());
00270         int num_of_second_task = atoi(argMap["first-to-last-rounds"].c_str());
00271         int num_of_third_task = atoi(argMap["last-to-first-rounds"].c_str());
00272         vector<int>* taskVector = new vector<int>();
00273         for(int i = 0 ; i < num_of_first_task ; i++)  taskVector->push_back(1);
00274         for(int i = 0 ; i < num_of_second_task ; i++)  taskVector->push_back(2);
00275         for(int i = 0 ; i < num_of_third_task ; i++)  taskVector->push_back(3);
00276         scramble(*taskVector);
00277 
00278   // let's get all our ModelComponent instances started:
00279             manager.start();
00280             for(map<string,string>::iterator it= argMap.begin(); it!= argMap.end() ; ++it) d->pushEvent("arg:"+ it->first+" value:"+it->second ) ;
00281   // let's display an ISCAN calibration grid:
00282             d->clearScreen();
00283             d->displayISCANcalib();
00284             d->waitForMouseClick();
00285             d->displayText("Here the experiment starts! click to start!");
00286             d->waitForMouseClick();
00287             d->clearScreen();
00288             //let's do calibration
00289             d->displayText("CLICK LEFT button to calibrate; RIGHT to skip");
00290             int cl = d->waitForMouseClick();
00291             if (cl == 1) d->displayEyeTrackerCalibration(3,5,1 , true);
00292             d->clearScreen();
00293 
00294             Uint32 fc = d->getUint32color(PixRGB<byte>(255,0,0));
00295             Uint32 sc = d->getUint32color(PixRGB<byte>(0,255,0));
00296             Uint32 tc = d->getUint32color(PixRGB<byte>(0,0,255));
00297             SDL_Surface* f_pad= getABlankSurface(36,34);
00298             SDL_Surface* s_pad= getABlankSurface(36,34);
00299             SDL_Surface* t_pad= getABlankSurface(36,34) ;
00300             fillRectangle(f_pad,fc,0,0,35 ,33);
00301             fillRectangle(s_pad,sc,0,0,35 ,33);
00302             fillRectangle(t_pad,tc,0,0,35 ,33);
00303             SDL_Rect cue_offset ;
00304             cue_offset.x = (d->getWidth() -36) /2;
00305             cue_offset.y = (d-> getHeight() - 34) /2;
00306         int fs = 0 ;
00307         int ss = 0;
00308         int ts = 0 ;
00309             for( uint r = 0 ; r < taskVector->size() ; r++ ){
00310                 d->showCursor(true);
00311                 d->displayText("click one of the  mouse buttons to start!");
00312                 d->waitForMouseClick() ;
00313                 d->showCursor(false) ;
00314                 d->clearScreen() ;
00315                 d->displayFixationBlink();
00316                 int task = taskVector->at(r) ;
00317                 vector<int> digits = getDigits(numOfDigits,argMap["include-zero"],argMap["digit-repeat"]);
00318                     int counter = 0 ;
00319                     while( counter < numOfDigits ){
00320                         if(Mix_PlayingMusic() == 0 ){
00321                                 //Play the music
00322                                 if( Mix_PlayMusic( audioMap[digits[counter]], 0 ) == -1 ) { return 1; }
00323                                 d->pushEvent("the "+stringify(counter)+"th  : " +stringify(digits[counter]));
00324                                 counter++ ;
00325                         }
00326                     }
00327                 //just hold it there to the end of the audio playing
00328                 while( Mix_PlayingMusic() == 1 ){}
00329                 if(cue_wait_frames != 0) d->waitFrames(cue_wait_frames) ;
00330                 std::string imst = "===== Showing image: def";
00331                 PixRGB<byte> cuecolor;
00332                 switch( task ){
00333                         case 1 : fs++ ; d->displaySDLSurfacePatch(f_pad , &cue_offset,NULL , -2,false, true); imst += "_first_"+stringify(fs)+".png" ; break ;
00334                         case 2 : ss++ ; d->displaySDLSurfacePatch(s_pad , &cue_offset,NULL , -2,false, true);imst += "_second_"+stringify(ss)+".png" ;break ;
00335                         case 3 : ts++ ; d->displaySDLSurfacePatch(t_pad , &cue_offset,NULL , -2,false, true);imst += "_third_" +stringify(ts)+".png";break ;
00336                 }
00337 
00338                 d->pushEvent(imst);
00339                 d->waitFrames(cue_onset_frames);
00340                 eyet->track(true);
00341                 d->clearScreen() ;
00342                 d->waitFrames(delay);
00343                 eyet->track(false);
00344                 d->displayText("SAY THE NUMBER LOUD!");
00345                 d->waitForMouseClick();
00346                 d->pushEvent("**************************************") ;
00347             }
00348             d->clearScreen();
00349             d->displayText("Experiment complete. Thank you!");
00350             d->waitForMouseClick();
00351 
00352 
00353           // stop all our ModelComponents
00354             manager.stop();
00355 
00356         //let's free up the audio files
00357         for( int i = 0 ; i < 10 ; i++ ){
00358                 Mix_FreeMusic(audioMap[i]);
00359         }
00360          //time to close the audio channel
00361         Mix_CloseAudio();
00362           // all done!
00363             return 0;
00364 }
00365 
00366 #endif // INVT_HAVE_LIBSDL_IMAGE
00367 
Generated on Sun May 8 08:40:10 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3