EyeSFile.C

Go to the documentation of this file.
00001 /*!@file Psycho/EyeSFile.C Read data from a .eyeS eye position file */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005   //
00005 // by the 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: Rob Peters <rjpeters at usc dot edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Psycho/EyeSFile.C $
00035 // $Id: EyeSFile.C 14730 2011-04-14 18:28:58Z lior $
00036 //
00037 
00038 #ifndef PSYCHO_EYESFILE_C_DEFINED
00039 #define PSYCHO_EYESFILE_C_DEFINED
00040 
00041 #include "Psycho/EyeSFile.H"
00042 
00043 #include "Component/ModelOptionDef.H"
00044 #include "Media/MediaOpts.H"
00045 #include "Psycho/PsychoOpts.H"
00046 #include "rutz/trace.h"
00047 
00048 #include <fstream>
00049 #include <iomanip>
00050 #include <sstream>
00051 
00052 // Used by: EyeSFile
00053 static const ModelOptionDef OPT_EyeSFileName =
00054   { MODOPT_ARG_STRING, "EyeSFileName", &MOC_EYETRACK, OPTEXP_CORE,
00055     "Name of the .eyeS file from which to read eye movement samples",
00056     "eyeS-fname", '\0', "<fname.eyeS>", "" };
00057 
00058 // Used by: EyeSFile
00059 static const ModelOptionDef OPT_EyeSNumSkip =
00060   { MODOPT_ARG(int), "EyeSNumSkip", &MOC_EYETRACK, OPTEXP_CORE,
00061     "Number of leading samples to skip in the .eyeS file",
00062     "eyeS-num-skip", '\0', "<int>", "0" };
00063 
00064 // Used by: EyeSFile
00065 const ModelOptionDef OPT_EyeSPeriod =
00066   { MODOPT_ARG(SimTime), "EyeSPeriod", &MOC_EYETRACK, OPTEXP_CORE,
00067     "Eye tracker sampling period in the .eyeS file",
00068     "eyeS-period", '\0', "<float>", "240Hz" };
00069 
00070 // Used by: EyeSFile
00071 const ModelOptionDef OPT_EyeSDims =
00072   { MODOPT_ARG(Dims), "EyeSDims", &MOC_EYETRACK, OPTEXP_CORE,
00073     "Stimulus dimensions for the eye samples in the .eyeS file",
00074     "eyeS-dims", '\0', "<w>x<h>", "0x0" };
00075 
00076 EyeSFile::EyeSFile(OptionManager& mgr)
00077   :
00078   ModelComponent(mgr, "EyeSFile", "EyeSFile"),
00079   itsEyeFname(&OPT_EyeSFileName, this),
00080   itsEyeTrash(&OPT_EyeSNumSkip, this),
00081   itsEyePeriod(&OPT_EyeSPeriod, this),
00082   itsRawInputDims(&OPT_EyeSDims, this),
00083   itsFile(0),
00084   itsEyeSample(0),
00085   itsPos(0, 0)
00086 {}
00087 
00088 EyeSFile::~EyeSFile()
00089 {}
00090 
00091 void EyeSFile::start2()
00092 {
00093   ASSERT(itsFile == 0);
00094 
00095   if (itsEyeFname.getVal().length() == 0)
00096     LFATAL("No --%s given!", itsEyeFname.getOptionDef()->longoptname);
00097 
00098   itsFile = new std::ifstream(itsEyeFname.getVal().c_str());
00099   if (!itsFile->is_open())
00100     LFATAL("Couldn't open .eyeS file '%s' for reading",
00101            itsEyeFname.getVal().c_str());
00102 
00103   // FIXME merge all this stuff with EyeTrackerSaccadeController
00104 
00105   // Look for auxiliary data files associated with the main .eyeS
00106   // file, and read data from them if present. Specifically, if
00107   // itsEyeFname is e.g. "foo.eyeS", then we will look for a file
00108   // "foo.eyeS.ntrash" to contain a value for itsEyeTrash, and we will
00109   // look for a file "foo.eyeS.rate" to contain a value for
00110   // itsEyePeriod. That way, those files can be generated once at the
00111   // same time that the .eyeS file itself is generated (probably from
00112   // some perl/matlab scripts). Note that the .rate file should
00113   // contain a suffix to indicate what units the value is in,
00114   // e.g. "240.19Hz" or "4.16337ms".
00115 
00116   {
00117     std::ifstream f((itsEyeFname.getVal() + ".npts").c_str());
00118     if (f.is_open())
00119       {
00120         uint npts = 0;
00121         f >> npts;
00122         if (!f.fail())
00123           LINFO("%s.npts = %u", itsEyeFname.getVal().c_str(), npts);
00124       }
00125   }
00126 
00127   {
00128     std::ifstream f((itsEyeFname.getVal() + ".ntrash").c_str());
00129     if (f.is_open())
00130       {
00131         int ntrash = 0;
00132         f >> ntrash;
00133         if (!f.fail())
00134           {
00135             LINFO("%s.ntrash = %d", itsEyeFname.getVal().c_str(), ntrash);
00136             const int oldval = itsEyeTrash.getVal();
00137             itsEyeTrash.setVal(ntrash);
00138             LINFO("reset --%s from %d to %d",
00139                   itsEyeFname.getOptionDef()->longoptname,
00140                   oldval, itsEyeTrash.getVal());
00141           }
00142       }
00143   }
00144 
00145   {
00146     std::ifstream f((itsEyeFname.getVal() + ".rate").c_str());
00147     if (f.is_open())
00148       {
00149         std::string rate;
00150         f >> rate;
00151         if (!f.fail())
00152           {
00153             LINFO("%s.rate = %s", itsEyeFname.getVal().c_str(), rate.c_str());
00154             const SimTime oldval = itsEyePeriod.getVal();
00155             itsEyePeriod.setValString(rate);
00156             LINFO("reset --%s from %fs (%fHz) to %fs (%fHz)",
00157                   itsEyePeriod.getOptionDef()->longoptname,
00158                   oldval.secs(), oldval.hertz(),
00159                   itsEyePeriod.getVal().secs(),
00160                   itsEyePeriod.getVal().hertz());
00161           }
00162       }
00163   }
00164 
00165   for (int i = 0; i < itsEyeTrash.getVal(); ++i)
00166     {
00167       std::string line;
00168       std::getline(*itsFile, line);
00169     }
00170 
00171   // count the number of lines AFTER the initial skipped lines
00172   itsEyeSample = 0;
00173 
00174   ASSERT(itsRawInputDims.getVal().isNonEmpty());
00175 }
00176 
00177 void EyeSFile::stop1()
00178 {
00179   ASSERT(itsFile != 0);
00180   itsFile->close();
00181   delete itsFile;
00182   itsFile = 0;
00183 }
00184 
00185 Point2D<int> EyeSFile::readUpTo(const SimTime& stime)
00186 {
00187   GVX_TRACE(__PRETTY_FUNCTION__);
00188 
00189   ASSERT(itsFile != 0);
00190 
00191   if (itsFile->eof())
00192     return Point2D<int>(-1,-1);
00193 
00194   double xsum = 0.0, ysum = 0.0;
00195   int pcount = 0;
00196 
00197   while (itsEyeSample * itsEyePeriod.getVal() < stime)
00198     {
00199       ++itsEyeSample;
00200       std::string line;
00201       std::getline(*itsFile, line);
00202       *itsFile >> std::ws;
00203       if (line.find("NaN") == line.npos)
00204         {
00205           double x, y, targetx, targety, ampl;
00206           int status, fixlen;
00207           std::istringstream iss(line);
00208 
00209           // see findSaccades.m for details on how the columns of
00210           // the .eyeS file are generated
00211           iss >> x >> y >> status >> targetx >> targety >> ampl >> fixlen;
00212           if (iss.fail())
00213             LFATAL("error while scanning %s:%d:\n%s",
00214                    itsEyeFname.getVal().c_str(), itsEyeSample,
00215                    line.c_str());
00216           xsum += x;
00217           ysum += y;
00218           ++pcount;
00219         }
00220 
00221       if (itsFile->eof())
00222         break;
00223 
00224       if (itsFile->fail())
00225         LFATAL("input failed at %s:%d",
00226                itsEyeFname.getVal().c_str(), itsEyeSample);
00227     }
00228 
00229   if (pcount > 0)
00230     {
00231       const int x = int(xsum/pcount + 0.5);
00232       const int y = int(ysum/pcount + 0.5);
00233 
00234       if (x >= 0 && x < itsRawInputDims.getVal().w() &&
00235           y >= 0 && y < itsRawInputDims.getVal().h())
00236         {
00237           itsPos = Point2D<int>(int(xsum/pcount), int(ysum/pcount));
00238         }
00239     }
00240 
00241   return itsPos;
00242 }
00243 
00244 Point2D<float> EyeSFile::getPos()
00245 {
00246   GVX_TRACE(__PRETTY_FUNCTION__);
00247 
00248   ASSERT(itsFile != 0);
00249 
00250   if (itsFile->eof())
00251     return Point2D<float>(-1,-1);
00252 
00253   std::string line;
00254   std::getline(*itsFile, line);
00255   *itsFile >> std::ws;
00256 
00257   std::istringstream iss(line);
00258 
00259   double x, y, targetx, targety, ampl;
00260   int status, fixlen;
00261   iss >> x >> y >> status >> targetx >> targety >> ampl >> fixlen;
00262   if (iss.fail())
00263     LFATAL("error while scanning %s:%d:\n%s",
00264         itsEyeFname.getVal().c_str(), itsEyeSample,
00265         line.c_str());
00266 
00267   if (itsFile->eof())
00268     return Point2D<float>(-1,-1);
00269 
00270   if (itsFile->fail())
00271     LFATAL("input failed at %s:%d",
00272         itsEyeFname.getVal().c_str(), itsEyeSample);
00273 
00274   return Point2D<float>(x,y);
00275 }
00276 
00277 int EyeSFile::lineNumber() const
00278 {
00279   return itsEyeSample;
00280 }
00281 
00282 // ######################################################################
00283 /* So things look consistent in everyone's emacs... */
00284 /* Local Variables: */
00285 /* mode: c++ */
00286 /* indent-tabs-mode: nil */
00287 /* End: */
00288 
00289 #endif // PSYCHO_EYESFILE_C_DEFINED
Generated on Sun May 8 08:41:12 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3