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 if (c == ' ') d->displayEyeTrackerCalibration(3, 3);
00142
00143
00144 d->clearScreen();
00145
00146 d->displayText("<SPACE> to start experiment");
00147 d->waitForKey();
00148
00149
00150 for (int im = 0; im < nimg; im++) {
00151 int imnum = imindex[im];
00152
00153
00154 d->clearScreen();
00155 LINFO("Loading '%s' / '%s'...", ilist[imnum].c_str(),tlist[imnum].c_str());
00156
00157
00158
00159 if(!Raster::fileExists(tlist[imnum]))
00160 {
00161
00162 manager.stop();
00163 LFATAL("i couldnt find image file %s", tlist[imnum].c_str());
00164 }
00165
00166 Image< PixRGB<byte> > img = Raster::ReadRGB(tlist[imnum]);
00167 Image< PixRGB<byte> > rndimg(d->getDims(), NO_INIT);
00168 rndimg.clear(d->getGrey());
00169 int rndx = 0,rndy = 0;
00170
00171 SDL_Surface *surf1 = d->makeBlittableSurface(img, true);
00172 char buf[256];
00173
00174 if(!Raster::fileExists(ilist[imnum]))
00175 {
00176 manager.stop();
00177 LFATAL("i couldnt find image file %s", ilist[imnum].c_str());
00178 }
00179 img = Raster::ReadRGB(ilist[imnum]);
00180 SDL_Surface *surf2 = d->makeBlittableSurface(img, true);
00181
00182
00183
00184
00185 if(!Raster::fileExists(rlist[imnum]))
00186 {
00187
00188 manager.stop();
00189 LFATAL(" i couldnt find image file %s", tlist[imnum].c_str());
00190 }
00191
00192 img = Raster::ReadRGB(rlist[imnum]);
00193 SDL_Surface *surf3 = d->makeBlittableSurface(img, true);
00194
00195
00196 usleep(200000);
00197
00198
00199 d->displayFixationBlink();
00200
00201 d->waitNextRequestedVsync(false, true);
00202
00203
00204 sprintf(buf, "===== Showing imagelet: %s at (%d, %d) =====",
00205 tlist[imnum].c_str(), rndx, rndy);
00206
00207 d->pushEvent(buf);
00208 d->displaySurface(surf1, 0, true);
00209 usleep(2000000);
00210
00211 d->clearScreen();
00212
00213
00214
00215
00216 et->track(true);
00217
00218
00219 d->pushEvent(std::string("===== Showing search image: ") + ilist[imnum] +
00220 std::string(" ====="));
00221
00222 d->displaySurface(surf2, 0, true);
00223
00224
00225 d->waitForKey();
00226
00227 et->track(false);
00228
00229
00230
00231
00232 d->pushEvent(std::string("===== Showing reporting image: ") + rlist[imnum] +
00233 std::string(" ====="));
00234 d->displaySurface(surf3, 0, true);
00235
00236 usleep(200000);
00237 d->displayText("Input the target number:");
00238
00239 string inputString = d->getString('\n');
00240
00241
00242 char tmp[40];
00243
00244
00245 ifstream specFile(slist[imnum].c_str(), ifstream::in);
00246
00247 bool found =false;
00248 string testLine;
00249 std::vector<std::string> specTokens;
00250
00251 if(specFile.is_open())
00252 {
00253 while(!specFile.eof() && !found)
00254 {
00255 getline(specFile, testLine);
00256 string::size_type loc = testLine.find("target", 0);
00257
00258 if(loc != string::npos)
00259 found = true;
00260 }
00261 if(!found)
00262 {
00263 manager.stop();
00264 LFATAL("couldnt find the target number from spec file");
00265 }
00266
00267 split(testLine," ", std::back_inserter(specTokens));
00268
00269 std::string responseString;
00270 responseString = inputString;
00271 int intResponse = atoi(responseString.c_str()), intActual = atoi(specTokens[1].c_str());
00272
00273 total++;
00274
00275 if (intResponse == intActual)
00276 {
00277 correct ++;
00278 accuracy = correct * 100 / total;
00279 sprintf(tmp, "Correct! Accuracy is %d%%", accuracy);
00280 d->displayText(tmp);
00281 d->pushEvent(std::string("===== Correct ====="));
00282 usleep(500000);
00283 }
00284 else
00285 {
00286 accuracy = correct * 100 / total;
00287 sprintf(tmp, "Wrong! Accuracy is %d%%", accuracy);
00288 d->displayText(tmp);
00289 d->pushEvent(std::string("===== Wrong ====="));
00290 usleep(500000);
00291 }
00292
00293 specFile.close();
00294 }
00295 else
00296 {
00297 d->displayText("no target file found!");
00298 LFATAL("couldnt open the file -%s-",slist[imnum].c_str());
00299 }
00300
00301
00302
00303 SDL_FreeSurface(surf1); SDL_FreeSurface(surf2); SDL_FreeSurface(surf3);
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 if (im==50)
00319 {
00320 d->displayText("You may take a break press space to continue when ready");
00321 d->waitForKey();
00322
00323 d->clearScreen();
00324 d->displayISCANcalib();
00325 d->waitForKey();
00326
00327 d ->displayText("<SPACE> to calibrate; other key to skip");
00328 int c = d->waitForKey();
00329 if (c == ' ') d->displayEyeTrackerCalibration(3, 3);
00330 }
00331
00332
00333
00334 et->recalibrate(d,15);
00335
00336 }
00337
00338 d->clearScreen();
00339 d->displayText("Experiment complete. Thank you!");
00340 d->waitForKey();
00341
00342
00343 manager.stop();
00344
00345
00346 return 0;
00347 }
00348
00349
00350
00351 extern "C" int main(const int argc, char** argv)
00352 {
00353
00354
00355
00356
00357 try
00358 {
00359 return submain(argc, argv);
00360 }
00361 catch (...)
00362 {
00363 REPORT_CURRENT_EXCEPTION;
00364 }
00365
00366 return 1;
00367 }
00368
00369
00370
00371
00372