psycho-stealth.C

Go to the documentation of this file.
00001 /*!@file AppPsycho/psycho-stealth.C Psychophysics display of primary task's
00002   search arrays followed by stealthy insertion of secondary task's
00003   search arrays */
00004 
00005 // //////////////////////////////////////////////////////////////////// //
00006 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00007 // University of Southern California (USC) and the iLab at USC.         //
00008 // See http://iLab.usc.edu for information about this project.          //
00009 // //////////////////////////////////////////////////////////////////// //
00010 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00011 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00012 // in Visual Environments, and Applications'' by Christof Koch and      //
00013 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00014 // pending; application number 09/912,225 filed July 23, 2001; see      //
00015 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00016 // //////////////////////////////////////////////////////////////////// //
00017 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00018 //                                                                      //
00019 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00020 // redistribute it and/or modify it under the terms of the GNU General  //
00021 // Public License as published by the Free Software Foundation; either  //
00022 // version 2 of the License, or (at your option) any later version.     //
00023 //                                                                      //
00024 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00027 // PURPOSE.  See the GNU General Public License for more details.       //
00028 //                                                                      //
00029 // You should have received a copy of the GNU General Public License    //
00030 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00031 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00032 // Boston, MA 02111-1307 USA.                                           //
00033 // //////////////////////////////////////////////////////////////////// //
00034 //
00035 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00036 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/AppPsycho/psycho-stealth.C $
00037 // $Id: psycho-stealth.C 8426 2007-05-24 06:57:57Z itti $
00038 //
00039 
00040 #include "Component/ModelManager.H"
00041 #include "Image/Image.H"
00042 #include "Psycho/PsychoDisplay.H"
00043 #include "Psycho/EyeTrackerConfigurator.H"
00044 #include "Psycho/EyeTracker.H"
00045 #include "GUI/GUIOpts.H"
00046 #include "Psycho/PsychoOpts.H"
00047 #include "Component/EventLog.H"
00048 #include "Component/ComponentOpts.H"
00049 #include "Raster/Raster.H"
00050 #include "Util/Types.H"
00051 #include <fstream>
00052 #include <string>
00053 
00054 // ######################################################################
00055 extern "C" int main(const int argc, char** argv)
00056 {
00057   MYLOGVERB = LOG_INFO;  // suppress debug messages
00058 
00059   // Instantiate a ModelManager:
00060   ModelManager manager("Psycho stealth");
00061 
00062   // Instantiate our various ModelComponents:
00063   nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00064   manager.addSubComponent(d);
00065 
00066   nub::soft_ref<EyeTrackerConfigurator>
00067     etc(new EyeTrackerConfigurator(manager));
00068   manager.addSubComponent(etc);
00069 
00070   nub::soft_ref<EventLog> el(new EventLog(manager));
00071   manager.addSubComponent(el);
00072 
00073   // set some display params
00074   //manager.setOptionValString(&OPT_SDLdisplayDims, "1280x1024");
00075   manager.setOptionValString(&OPT_SDLdisplayDims, "1024x768");
00076   d->setModelParamVal("PsychoDisplayBackgroundColor", PixRGB<byte>(0));
00077   d->setModelParamVal("PsychoDisplayTextColor", PixRGB<byte>(255));
00078   d->setModelParamVal("PsychoDisplayBlack", PixRGB<byte>(255));
00079   d->setModelParamVal("PsychoDisplayWhite", PixRGB<byte>(128));
00080   d->setModelParamVal("PsychoDisplayFixSiz", 5);
00081   d->setModelParamVal("PsychoDisplayFixThick", 5);
00082   manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy");
00083   manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00084 
00085 
00086   // Parse command-line:
00087   if (manager.parseCommandLine(argc, argv, "<fileList> <stealthPrefix>"
00088                                "<numStealth>",
00089                                3,-1)==false)
00090     return(1);
00091 
00092   // hook our various babies up and do post-command-line configs:
00093   nub::soft_ref<EyeTracker> et = etc->getET();
00094   d->setEyeTracker(et);
00095   d->setEventLog(el);
00096   et->setEventLog(el);
00097 
00098   // let's get all our ModelComponent instances started:
00099   manager.start();
00100 
00101   // let's display an ISCAN calibration grid:
00102   d->clearScreen();
00103   d->displayISCANcalib();
00104   d->waitForKey();
00105 
00106   // let's do an eye tracker calibration:
00107   d->displayText("<SPACE> to calibrate; other key to skip");
00108   int c = d->waitForKey();
00109   if (c == ' ') d->displayEyeTrackerCalibration(3, 3);
00110 
00111   d->clearScreen();
00112 
00113   // setup array of movie indices:
00114   std::ifstream file(manager.getExtraArg(0).c_str());
00115   if (file == 0) LFATAL("Couldn't open object file: '%s'",
00116                         manager.getExtraArg(0).c_str());
00117   // prefix or path to stealth trials
00118   std::string stealthPrefix =  manager.getExtraArg(1);
00119   // number of items per stealth trial
00120   int numStealth = atoi (manager.getExtraArg(2).c_str());
00121 
00122   std::string line;
00123   // for online feedback on primary task T1
00124   int correct = 0, accuracy = 100, total = 0;
00125   // find the number of reports on M,T,D for the secondary task T2
00126   int N[numStealth];
00127   for (int i = 0; i < numStealth; i++) N[i] = 0;
00128   while(getline(file, line))
00129     {
00130       // parse the line to get the file names
00131       // format: <image> <noCheat> <checkResponse> <reco>
00132       std::string::size_type end = line.find_first_of(" ");
00133       std::string::size_type start = 0;
00134       int i = 0; std::string imageName, noCheatName, checkName, recoName;
00135       while (end != std::string::npos) {
00136         std::string token = line.substr(start, end-start);
00137         switch(i)
00138           {
00139           case 0:
00140             imageName = token;
00141             break;
00142           case 1:
00143             noCheatName = token;
00144             break;
00145           case 2:
00146             checkName = token;
00147             break;
00148           }
00149         start = end + 1;
00150         end = line.find_first_of(" ", start);
00151         i ++;
00152       }
00153       // last token
00154       recoName = line.substr(start);
00155 
00156       // load up the frame and show a fixation cross on a blank screen:
00157       d->clearScreen();
00158 
00159       LINFO("Loading '%s'...", imageName.c_str());
00160       Image< PixRGB<byte> > image =
00161         Raster::ReadRGB(imageName);
00162 
00163       SDL_Surface *surf = d->makeBlittableSurface(image, true);
00164 
00165       LINFO("'%s' ready.", imageName.c_str());
00166 
00167       // ready to go whenever the user is ready:
00168       d->displayText("hit any key when ready");
00169       d->waitForKey();
00170       d->waitNextRequestedVsync(false, true);
00171 
00172       // start the eye tracker:
00173       et->track(true);
00174       d->pushEvent(std::string("===== Showing image: ") +imageName + " =====");
00175 
00176       // blink the fixation:
00177       d->displayFixationBlink();
00178 
00179       // show the image:
00180       d->displaySurface(surf, -2, true);
00181 
00182       if (imageName.find(stealthPrefix, 0) != std::string::npos) {
00183         // flash T2 trial
00184         for (int j = 0; j < 7; j ++) d->waitNextRequestedVsync();
00185       }
00186       else {
00187         // T1 trial
00188         c = d->waitForKey();
00189       }
00190 
00191       // free the image:
00192       SDL_FreeSurface(surf);
00193 
00194       // stop the eye tracker:
00195       usleep(50000);
00196       et->track(false);
00197 
00198       // flash a random grid of numbers and check response to prevent
00199       // cheating
00200       LINFO("Loading '%s'...", noCheatName.c_str());
00201 
00202       Image< PixRGB<byte> > noCheat =
00203         Raster::ReadRGB(noCheatName);
00204 
00205       surf = d->makeBlittableSurface(noCheat, true);
00206 
00207 
00208       LINFO("'%s' ready.", noCheatName.c_str());
00209       d->pushEvent(std::string("===== Showing noCheat: ") + noCheatName
00210                    + " =====");
00211 
00212       // flash the image for 99ms:
00213       d->displaySurface(surf, -2, true);
00214       for (int j = 0; j < 6; j ++) d->waitNextRequestedVsync();
00215 
00216        // free the image:
00217       SDL_FreeSurface(surf);
00218 
00219       // wait for response:
00220       d->displayText("Enter the number at the target location");
00221       c = d->waitForKey();
00222       int c2 = d->waitForKey();
00223 
00224       if (imageName.find(stealthPrefix, 0) == std::string::npos) {
00225         // check response for the T1 trial
00226         std::ifstream check (checkName.c_str());
00227         if (check == 0) LFATAL("Couldn't open check file: '%s'",
00228                                checkName.c_str());
00229         std::string response;
00230         total ++;
00231         while (getline(check, response))
00232           {
00233             LINFO (" reading from %s", checkName.c_str());
00234             LINFO (" subject entered %d%d", c, c2);
00235             LINFO (" reading %c%c from %s", response[0], response[1],
00236                    checkName.c_str());
00237             // check the response
00238             char tmp[40];
00239             if (((int)response[0] == c) && ((int)response[1] == c2))
00240               {
00241                 correct ++;
00242                 accuracy = correct * 100 / total;
00243                 sprintf(tmp, "Correct! Accuracy is %d%%", accuracy);
00244                 d->displayText(tmp);
00245                 d->pushEvent(std::string("===== Correct ====="));
00246               }
00247             else
00248               {
00249                 accuracy = correct * 100 / total;
00250                 sprintf(tmp, "Wrong! Accuracy is %d%%", accuracy);
00251                 d->displayText(tmp);
00252                 d->pushEvent(std::string("===== Wrong ====="));
00253               }
00254             // maintain display
00255             for (int j = 0; j < 30; j ++) d->waitNextRequestedVsync();
00256           }
00257       }
00258       else {
00259         // check response for the T2 trial
00260         std::ifstream reco (recoName.c_str()); std::string sline;
00261         if (reco == 0) LFATAL("Couldn't open reco file: '%s'",
00262                                recoName.c_str());
00263         std::string response; int lineNum = 0;
00264         LINFO (" reading from %s", recoName.c_str());
00265         LINFO (" subject entered %c%c", c, c2);
00266         // compare subject's response to that stored in the reco file
00267         bool match = false;
00268         while(getline(reco, sline))
00269           {
00270             // parse the line to get the correct response
00271             // format: <row> <col> <imageName> <response>
00272             std::string::size_type end = sline.find_first_of(" "), start = 0;
00273             std::string response;
00274             while (end != std::string::npos) {
00275               std::string token = sline.substr(start, end-start);
00276               start = end + 1;
00277               end = sline.find_first_of(" ", start);
00278             }
00279             response = sline.substr(start);
00280             LINFO (" reading %c%c from %s", response[0], response[1],
00281                        recoName.c_str());
00282             // does the report match the stored response?
00283             if (((int)response[0] == c) && ((int)response[1] == c2))
00284               {
00285                 // found match, update the number of reports
00286                 N[lineNum] = N[lineNum] + 1;
00287                 match = true;
00288                 char s[40]; sprintf(s, "N = ( ");
00289                 for (int i = 0; i < numStealth; i ++)
00290                   sprintf(s, "%s %d ", s, N[i]);
00291                 LINFO ("%s )", s);
00292                 break;
00293               }
00294             lineNum ++; // parse the next line
00295             i = 0; // reset token index for parsing the next line
00296           }
00297         if (match == false)
00298           d->displayText("Oops, You entered an invalid number...");
00299 
00300         // maintain display
00301         for (int j = 0; j < 30; j ++) d->waitNextRequestedVsync();
00302 
00303       }
00304 
00305     }
00306 
00307   d->clearScreen();
00308   d->displayText("Experiment complete. Thank you!");
00309   d->waitForKey();
00310 
00311   // output the number of reports
00312   char s[40]; sprintf(s, "N = ( ");
00313   for (int i = 0; i < numStealth; i ++)
00314     sprintf(s, "%s %d ", s, N[i]);
00315   LINFO ("%s )", s);
00316   LINFO ("accuracy = %d%%", accuracy);
00317 
00318   // stop all our ModelComponents
00319   manager.stop();
00320 
00321   // all done!
00322   return 0;
00323 }
00324 
00325 // ######################################################################
00326 /* So things look consistent in everyone's emacs... */
00327 /* Local Variables: */
00328 /* indent-tabs-mode: nil */
00329 /* End: */
Generated on Sun May 8 08:40:10 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3