00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
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
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
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
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
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
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
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
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
00210
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
00284
00285
00286
00287
00288
00289 #endif // PSYCHO_EYESFILE_C_DEFINED