psycho-geon-relations.c

00001 /*!@file AppPsycho/psycho-geon-relations.C Psychophysics display of geon images of Marks relations experiment */
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-geon-relations.c $
00035 // $Id: psycho-geon-relations.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 <fstream>
00050 #include <ctime>
00051 #include <SDL/SDL_mixer.h> //for playing sounds
00052 #include <stdio.h>
00053 
00054 using namespace std;
00055 
00056 char waitForResp(double WaitTime, double StartMeasure, *char keys, int NumOfKeys);
00057 int WrightResults2File(string FileName,int* IsCorrect, double* RT,char* SubResp, char* CorrectResp, int NumOfTrials);
00058 
00059 
00060 // ######################################################################
00061 extern "C" int main(const int argc, char** argv)
00062 {
00063   MYLOGVERB = LOG_INFO;  // suppress debug messages
00064 
00065   // Instantiate a ModelManager:
00066   ModelManager manager("Psycho Still");
00067 
00068   // Instantiate our various ModelComponents:
00069   nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00070   manager.addSubComponent(d);
00071 
00072   nub::soft_ref<EyeTrackerConfigurator>
00073     etc(new EyeTrackerConfigurator(manager));
00074   manager.addSubComponent(etc);
00075 
00076   nub::soft_ref<EventLog> el(new EventLog(manager));
00077   manager.addSubComponent(el);
00078 
00079     int NumOfKeys=3;
00080     char keys[NumOfKeys]={'z', ',', '.'}; //from left to right, the key specified means object 1,2,3
00081 
00082 
00083 
00084 
00085   // Parse command-line:
00086   // Subject Run isAdapt(1or0) MaleOrFemale
00087   if (manager.parseCommandLine(argc, argv,
00088                                "<img1.ppm> ... <imgN.ppm>", 1, -1)==false){
00089         cout<<"please give the following arguments:\n Subject-Initials Run-Number  PresentationFrames(1 sec is 30 frames) MaleOrFemale(M for Male, F you guessed it...) Handedness(R L)"<< endl;
00090     cout<<"the keys for objects 1,2,3 are, respectively the keys:"<< keys[0]<< ", "<<keys[1] <<", "<< keys[2]<<endl;
00091         return(1);
00092         }
00093 
00094         string Sub=manager.getExtraArg(0);
00095         string Run=manager.getExtraArg(1);
00096         string PT=manager.getExtraArg(2);
00097         const char *pp;
00098         pp=PT.c_str();
00099         int PresentationFrames=atoi(pp);
00100         //int PresentationTime=(int)PT[0]-48;//atoi(PT[0].c_str());
00101         cout<<"presentation time is:"<<(PresentationFrames/30)<<" seconds"<<endl;
00102         string Gender=manager.getExtraArg(3);
00103         string Handedness=manager.getExtraArg(4);
00104 
00105         string DataDir="/lab/ilab19/geonexp/GRET/Data/";
00106         string psyFileName=DataDir + "GRET_Run" + Run + "_"+ Sub+"_StimONFrames-"+PT+"_"+Gender+"_"+Handedness+".psy";
00107         manager.setOptionValString(&OPT_EventLogFileName, psyFileName);
00108         manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00109 
00110         d->pushEvent(std::string("Run=") + Run + "\n" + Sub +"\nGender="+ Gender);
00111 
00112 
00113 
00114 
00115   // hook our various babies up and do post-command-line configs:
00116   nub::soft_ref<EyeTracker> et = etc->getET();
00117   d->setEyeTracker(et);
00118   d->setEventLog(el);
00119   et->setEventLog(el);
00120 
00121   // let's get all our ModelComponent instances started:
00122   manager.start();
00123 
00124   // let's do an eye tracker calibration:
00125   et->calibrate(d);
00126 
00127   d->clearScreen();
00128   d->displayText("<SPACE> for random play; other key for ordered");
00129   //int c = d->waitForKey();
00130 
00131   // setup array of movie indices:
00132   //uint nbimgs = manager.numExtraArgs(); int index[nbimgs];
00133   //for (uint i = 0; i < nbimgs; i ++) index[i] = i;
00134   //if (c == ' ') { LINFO("Randomizing images..."); randShuffle(index, nbimgs); }
00135 
00136   //Reads the Images sequence text file:
00137     string FileName;
00138 
00139     string ExpDir="/lab/ilab19/geonexp/GRET/sequences/";
00140     string ImgDir="/lab/ilab19/geonexp/GRET/images/";
00141 
00142 
00143         FileName=ExpDir+"GeonRelationsET_Run"+Run+".txt";
00144 
00145 
00146     cout<<FileName<<endl;
00147     const char *FileNameP=FileName.c_str();
00148 
00149 
00150   ifstream RunFile (FileNameP);
00151   string  u;
00152 
00153   int NumOfTrials, j;
00154 
00155   getline(RunFile, u);
00156   cout<<u;
00157   const char *p;
00158   p=u.c_str();
00159   NumOfTrials=atoi(p);
00160   string ImageSequence[NumOfTrials];
00161   double RT[NumOfTrials]; //The reaction time for each trial
00162   char SubResp[NumOfTrials];//The actual response in each trial
00163   int IsCorrect[NumOfTrials]; // whether the response was correct (=1) incorrect (=0) or no response recorded (=-1)
00164   char  Correct_Response[NumOfTrials]; //The key that the subject should have pressed
00165 
00166   for(j=0; j<NumOfTrials; j++){
00167     getline(RunFile, ImageSequence[j]);
00168     ImageSequence[j]= ImgDir +ImageSequence[j];
00169     cout <<ImageSequence[j]<<endl;
00170   }
00171 
00172   RunFile.close();
00173 
00174   double StartMeasure;
00175   double Now;
00176   char Response;
00177 
00178   //setting up the audio (for the error-feedback)
00179   Mix_Music* recallCueMusic = NULL;
00180   //now let's open the audio channel
00181   if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 ){
00182        LINFO( "did not open the mix-audio") ;
00183        return -1 ;
00184        }
00185   SoundFile='/lab/ilab19/geonexp/GRET/images/beep-2.wav';
00186   BipSound = Mix_LoadMUS(SoundFile);
00187 
00188 
00189 
00190 
00191 
00192   LINFO("Ready to go");
00193 
00194   // main loop:
00195   for (int i = 0; i < NumOfTrials; i ++)
00196     {
00197       // load up the frame and show a fixation cross on a blank screen:
00198       d->clearScreen();
00199       LINFO("Loading '%s'...", ImageSequence[i].c_str());
00200       Image< PixRGB<byte> > image =
00201         Raster::ReadRGB(ImageSequence[i]);
00202 
00203       SDL_Surface *surf = d->makeBlittableSurface(image, true);
00204 
00205       LINFO("'%s' ready.", ImageSequence[i].c_str());
00206       d->displayFixation();
00207 
00208       // ready to go whenever the user is ready:
00209       d->waitForKey();
00210       d->waitNextRequestedVsync(false, true);
00211       d->pushEvent(std::string("===== Showing image: ") +
00212                    ImageSequence[i] + " =====");
00213 
00214           //Finding out what object it is
00215           Current_Obj=ImageSequence[i][3];
00216           Correct_Response[i]=keys[ImageSequence[i][3]-1];
00217 
00218       // start the eye tracker:
00219       et->track(true);
00220 
00221       // blink the fixation:
00222       d->displayFixationBlink();
00223 
00224       // show the image:
00225       d->displaySurface(surf, -2);
00226 
00227       // Recording response:
00228           StartMeasure=d->getTimerValue();
00229           Response=waitForResp((PresentationFrames/30),  StartMeasure,  keys,  NumOfKeys); //see function bellow
00230           if (Response!='0'){RT[i]=((d->getTimerValue())-StartMeasure);};
00231           cout<<Response<<endl;
00232 
00233           //continues to present the image for the time specified
00234           Now = d->getTimerValue();
00235           while ((Now-StartMeasure)<(PresentationFrames/30)) { d->waitFrames(1);};
00236 
00237       // free the image:
00238       SDL_FreeSurface(surf);
00239 
00240       // make sure display if off before we stop the tracker:
00241       d->clearScreen();
00242 
00243       // stop the eye tracker:
00244       usleep(50000);
00245       et->track(false);
00246 
00247           //recording response if it wasn't yet recorded
00248           if (Response=='0') {Response=waitForResp(((PresentationFrames/30)+1),  StartMeasure,  keys,  NumOfKeys);}
00249           if (Response!='0'){RT[i]=((d->getTimerValue())-StartMeasure);}else{RT[i]=-1;};
00250           SubResp[i]=Response;
00251 
00252 
00253           //feedback if error
00254           if (Response!=Correct_Response){
00255                   IsCorrect[i]=0;
00256               if(task == 0){if( Mix_PlayMusic( BipSound, 0 ) == -1 ) { return 1; }
00257                                     while( Mix_PlayingMusic() == 1 ){}
00258                 }else{
00259                 IsCorrect[i]=1;
00260                 }
00261         }
00262         string BehaveFileName=DataDir + "Behav_GRET_Run" + Run + "_"+ Sub+"_StimONFrames-"+PT+"_"+Gender+"_"+Handedness+".bhv";
00263         WrightResults2File(BehaveFileName,IsCorrect,  RT, SubResp,  Correct_Response, NumOfTrials);
00264 
00265   d->clearScreen();
00266   d->displayText("Experiment complete. Thank you!");
00267   d->waitForKey();
00268 
00269   // stop all our ModelComponents
00270   manager.stop();
00271 
00272   // all done!
00273   return 0;
00274 
00275 }
00276 
00277 
00278 // ######################################################################
00279 /* So things look consistent in everyone's emacs... */
00280 /* Local Variables: */
00281 /* indent-tabs-mode: nil */
00282 /* End: */
00283 
00284 // ######################################################################
00285 char waitForResp(double WaitTime, double StartMeasure, *char keys, int NumOfKeys)
00286 {
00287   // clear the input buffer before we get started if doWait is set to true
00288   while (checkForKey() != -1) ;
00289 
00290   double Now=StartMeasure;
00291   pushEventBegin("waitForResp");
00292   SDL_Event event;
00293   int Stop=0;
00294 
00295   do {
00296 
00297         Now = d->getTimerValue() ;
00298         SDL_PollEvent(&event);
00299         if (event.type == SDL_KEYDOWN){
00300 
00301                 for (aa=0; aa<NumOfKeys; aa ++){ if  ((char(event.key.keysym.unicode))==keys[aa]) {Stop=1}}
00302         }
00303 
00304    } while (!Stop && (Now-StartMeasure)<WaitTime);
00305 
00306   if event.type==SDL_KEYDOWN{
00307 
00308         int key = event.key.keysym.unicode;
00309         char c; if (key >= 32 && key < 128) c = char(key); else c = '?';
00310         pushEventEnd(sformat("waitForResp - got %d (%c)", key, c));
00311 
00312         // abort if it was ESC:
00313         if (key == 27) LFATAL("Aborting on [ESC] key");
00314 
00315         return c;
00316 
00317   }else{  return '0';}
00318 
00319 }
00320 
00321 int WrightResults2File(string FileName,int* IsCorrect, double* RT,char* SubResp, char* CorrectResp, int NumOfTrials){
00322    /* function wrights the behavioral results of Mark's Geon Relations ET
00323      * experimnt into a text file */
00324 
00325     string ExpDir="/lab/ilab19/geonexp/GRET/Data/";
00326     FileName=ExpDir+FileName;
00327     const char *FileNameP=FileName.c_str();
00328     FILE * pFile;
00329     pFile = fopen (FileNameP,"w");
00330 
00331 
00332 
00333 
00334     int ii;
00335 
00336     for (ii=0; ii<NumOfTrials; ii ++){
00337         fprintf(pFile, "%i %f %c %c \n", IsCorrect[ii], RT[ii], SubResp[ii], CorrectResp[ii]);
00338 
00339     }
00340 
00341     fclose (pFile);
00342 
00343     return 0;
00344 
00345 
00346 
00347 
00348 
00349 
00350 }
Generated on Sun May 8 08:04:12 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3