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
00039 #include "Component/ModelManager.H"
00040 #include "Image/ColorOps.H"
00041 #include "Image/CutPaste.H"
00042 #include "Image/Image.H"
00043 #include "Image/MathOps.H"
00044 #include "Psycho/PsychoDisplay.H"
00045 #include "Psycho/EyeTrackerConfigurator.H"
00046 #include "Psycho/EyeTracker.H"
00047 #include "Psycho/PsychoOpts.H"
00048 #include "Component/EventLog.H"
00049 #include "Component/ComponentOpts.H"
00050 #include "Raster/Raster.H"
00051 #include "Util/MathFunctions.H"
00052 #include "Util/StringUtil.H"
00053
00054 #include <ctype.h>
00055 #include <vector>
00056 #include <string>
00057 #include <fstream>
00058
00059 using namespace std;
00060
00061
00062 #define NMASK 10
00063
00064
00065 static int submain(const int argc, char** argv)
00066 {
00067 MYLOGVERB = LOG_INFO;
00068
00069
00070 ModelManager manager("Psycho Search");
00071
00072
00073 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager));
00074 manager.addSubComponent(d);
00075
00076 nub::soft_ref<EyeTrackerConfigurator>
00077 etc(new EyeTrackerConfigurator(manager));
00078 manager.addSubComponent(etc);
00079
00080 nub::soft_ref<EventLog> el(new EventLog(manager));
00081 manager.addSubComponent(el);
00082
00083 manager.setOptionValString(&OPT_EventLogFileName, "psychodata.psy");
00084 manager.setOptionValString(&OPT_EyeTrackerType, "ISCAN");
00085
00086
00087 if (manager.parseCommandLine(argc, argv, "<imagelist.txt>", 1, 1) == false)
00088 return(1);
00089
00090
00091 nub::soft_ref<EyeTracker> et = etc->getET();
00092 d->setEyeTracker(et);
00093 d->setEventLog(el);
00094 et->setEventLog(el);
00095
00096
00097 manager.start();
00098
00099
00100
00101 FILE *f = fopen(manager.getExtraArg(0).c_str(), "r");
00102 if (f == NULL) LFATAL("Cannot read stimulus file");
00103 char line[1024];
00104 std::vector<std::string> ilist, tlist, rlist, slist;
00105
00106 int correct = 0, accuracy = 100, total = 0;
00107
00108 while(fgets(line, 1024, f))
00109 {
00110 std::vector<std::string> tokens;
00111
00112
00113
00114
00115 LINFO("line reads %s",line);
00116 split(line," ", std::back_inserter(tokens));
00117
00118
00119 tlist.push_back(std::string(tokens[0]));
00120 ilist.push_back(std::string(tokens[1]));
00121 rlist.push_back(std::string(tokens[2]));
00122 slist.push_back(std::string(tokens[3]));
00123 LINFO("\nNew pair \nline1 reads: %s, \nline2 reads:%s, \nline 3 reads %s,\nline 4 reads %s,",tokens[0].c_str(), tokens[1].c_str(),tokens[2].c_str(), tokens[3].c_str());
00124
00125 }
00126 fclose(f);
00127
00128
00129 int nimg = ilist.size(); int imindex[nimg];
00130 for (int i = 0; i < nimg; i ++) imindex[i] = i;
00131 randShuffle(imindex, nimg);
00132
00133
00134 d->clearScreen();
00135 d->displayISCANcalib();
00136 d->waitForKey();
00137
00138
00139 d->displayText("<SPACE> to calibrate; other key to skip");
00140 int c = d->waitForKey();
00141
00142
00143 if (c == ' ')
00144 {
00145 et->track(true);
00146 et->calibrateOnline(d);
00147 et->track(false);
00148 }
00149
00150
00151 d->clearScreen();
00152
00153 d->displayText("<SPACE> to start experiment");
00154 d->waitForKey();
00155
00156
00157 for (int im = 0; im < nimg; im++) {
00158 int imnum = imindex[im];
00159
00160
00161 d->clearScreen();
00162 LINFO("Loading '%s' / '%s'...", ilist[imnum].c_str(),tlist[imnum].c_str());
00163
00164
00165
00166 if(!Raster::fileExists(tlist[imnum]))
00167 {
00168
00169 manager.stop();
00170 LFATAL("i couldnt find image file %s", tlist[imnum].c_str());
00171 }
00172
00173 Image< PixRGB<byte> > img = Raster::ReadRGB(tlist[imnum]);
00174 Image< PixRGB<byte> > rndimg(d->getDims(), NO_INIT);
00175 rndimg.clear(d->getGrey());
00176 int rndx = 0,rndy = 0;
00177
00178 SDL_Surface *surf1 = d->makeBlittableSurface(img, true);
00179 char buf[256];
00180
00181 if(!Raster::fileExists(ilist[imnum]))
00182 {
00183 manager.stop();
00184 LFATAL("i couldnt find image file %s", ilist[imnum].c_str());
00185 }
00186 img = Raster::ReadRGB(ilist[imnum]);
00187 SDL_Surface *surf2 = d->makeBlittableSurface(img, true);
00188
00189
00190
00191
00192 if(!Raster::fileExists(rlist[imnum]))
00193 {
00194
00195 manager.stop();
00196 LFATAL(" i couldnt find image file %s", tlist[imnum].c_str());
00197 }
00198
00199 img = Raster::ReadRGB(rlist[imnum]);
00200 SDL_Surface *surf3 = d->makeBlittableSurface(img, true);
00201
00202
00203 usleep(200000);
00204
00205
00206 d->displayFixationBlink();
00207
00208 d->waitNextRequestedVsync(false, true);
00209
00210
00211 sprintf(buf, "===== Showing imagelet: %s at (%d, %d) =====",
00212 tlist[imnum].c_str(), rndx, rndy);
00213
00214 d->pushEvent(buf);
00215 d->displaySurface(surf1, 0, true);
00216 usleep(2000000);
00217
00218 d->clearScreen();
00219
00220
00221
00222
00223 et->track(true);
00224
00225
00226 d->pushEvent(std::string("===== Showing search image: ") + ilist[imnum] +
00227 std::string(" ====="));
00228
00229 d->displaySurface(surf2, 0, true);
00230
00231 Timer timer(100);
00232 timer.reset();
00233 double startTime=timer.getSecs();
00234
00235 bool timeUp=false;
00236 while(d->checkForKey()<0 && !timeUp)
00237 {
00238 if(timer.getSecs() > startTime +10)
00239 {
00240 timeUp=true;
00241 d->pushEvent(std::string("===== Time Up ====="));
00242 }
00243
00244 }
00245
00246
00247
00248 et->track(false);
00249
00250
00251
00252
00253 d->pushEvent(std::string("===== Showing reporting image: ") + rlist[imnum] +
00254 std::string(" ====="));
00255 d->displaySurface(surf3, 0, true);
00256
00257 usleep(200000);
00258 d->displayText("Input the target number:");
00259
00260 string inputString = d->getString('\n');
00261
00262
00263 char tmp[40];
00264
00265
00266 ifstream specFile(slist[imnum].c_str(), ifstream::in);
00267
00268 bool found =false;
00269 string testLine;
00270 std::vector<std::string> specTokens;
00271
00272 if(specFile.is_open())
00273 {
00274 while(!specFile.eof() && !found)
00275 {
00276 getline(specFile, testLine);
00277 string::size_type loc = testLine.find("target", 0);
00278
00279 if(loc != string::npos)
00280 found = true;
00281 }
00282 if(!found)
00283 {
00284 manager.stop();
00285 LFATAL("couldnt find the target number from spec file");
00286 }
00287
00288 split(testLine," ", std::back_inserter(specTokens));
00289
00290 std::string responseString;
00291 responseString = inputString;
00292 int intResponse = atoi(responseString.c_str()), intActual = atoi(specTokens[1].c_str());
00293
00294 total++;
00295
00296 if (intResponse == intActual)
00297 {
00298 correct ++;
00299 accuracy = correct * 100 / total;
00300 sprintf(tmp, "Correct! Accuracy is %d%%", accuracy);
00301 d->displayText(tmp);
00302 d->pushEvent(std::string("===== Correct ====="));
00303 usleep(500000);
00304 }
00305 else
00306 {
00307 accuracy = correct * 100 / total;
00308 sprintf(tmp, "Wrong! Accuracy is %d%%", accuracy);
00309 d->displayText(tmp);
00310 d->pushEvent(std::string("===== Wrong ====="));
00311 usleep(500000);
00312 }
00313
00314 specFile.close();
00315 }
00316 else
00317 {
00318 d->displayText("no target file found!");
00319 LFATAL("couldnt open the file -%s-",slist[imnum].c_str());
00320 }
00321
00322
00323
00324 SDL_FreeSurface(surf1); SDL_FreeSurface(surf2); SDL_FreeSurface(surf3);
00325
00326
00327
00328 if (im > 0 && im % 20 == 0) {
00329 d->displayText("Ready for quick recalibration");
00330 d->waitForKey();
00331 d->clearScreen();
00332 d->displayISCANcalib();
00333
00334 d->waitForKey();
00335 et->track(true);
00336 et->calibrateOnline(d);
00337 et->track(false);
00338 d->clearScreen();
00339 d->displayText("Ready to continue with the images");
00340 d->waitForKey();
00341 }
00342
00343
00344
00345 if (im==50)
00346 {
00347 d->displayText("You may take a break press space to continue when ready");
00348 d->waitForKey();
00349
00350 d->clearScreen();
00351 d->displayISCANcalib();
00352 d->waitForKey();
00353
00354 d ->displayText("<SPACE> to calibrate; other key to skip");
00355 int c = d->waitForKey();
00356 if (c == ' ')
00357
00358 {
00359 et->track(true);
00360 et->calibrateOnline(d);
00361 et->track(false);
00362 }
00363
00364
00365 }
00366 }
00367 d->clearScreen();
00368 d->displayText("Experiment complete. Thank you!");
00369 d->waitForKey();
00370
00371
00372 manager.stop();
00373
00374
00375 return 0;
00376 }
00377
00378
00379
00380 extern "C" int main(const int argc, char** argv)
00381 {
00382
00383
00384
00385
00386 try
00387 {
00388 return submain(argc, argv);
00389 }
00390 catch (...)
00391 {
00392 REPORT_CURRENT_EXCEPTION;
00393 }
00394
00395 return 1;
00396 }
00397
00398
00399
00400
00401