00001 /*!@file AppPsycho/psycho-skin-asindexing.c Psychophysics main application for indexing experiment */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // 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: Laurent Itti <itti@usc.edu> 00034 // 00035 // 2008-02-20 16:14:27Z nnoori $ 00036 //written by Nader Noori 00037 00038 // 00039 #ifndef INVT_HAVE_LIBSDL_IMAGE 00040 00041 #include <cstdio> 00042 int main() 00043 { 00044 fprintf(stderr, "The SDL_image library must be installed to use this program\n"); 00045 return 1; 00046 } 00047 00048 #else 00049 00050 00051 00052 /* 00053 Attention: SDL_image is needed for linking 00054 00055 */ 00056 00057 #include "Component/ModelManager.H" 00058 #include "Image/Image.H" 00059 #include "Psycho/PsychoDisplay.H" 00060 #include "Psycho/EyeTrackerConfigurator.H" 00061 #include "Psycho/EyeTracker.H" 00062 #include "Psycho/PsychoOpts.H" 00063 #include "Component/EventLog.H" 00064 #include "Component/ComponentOpts.H" 00065 #include "Raster/Raster.H" 00066 #include "Util/MathFunctions.H" 00067 #include "Util/Types.H" 00068 #include <iostream> 00069 #include <fstream> 00070 #include <SDL/SDL.h> 00071 #include <SDL/SDL_image.h> 00072 #include "psycho-skin-resize.h" 00073 #include <stdio.h> 00074 #include <stdlib.h> 00075 #include <map> 00076 #include <time.h> 00077 #include "psycho-skin-mapgenerator.h" 00078 #include <sstream> 00079 00080 00081 using namespace std; 00082 00083 ModelManager manager("Psycho Parallel Search"); 00084 nub::soft_ref<PsychoDisplay> d(new PsychoDisplay(manager)); 00085 bool programQuit = false ; 00086 map<string,string> skinFileMap ; 00087 const int NUMBER_OF_CLASSES = 6; 00088 const int IMAGE_WIDTH = 128 ; 00089 const string classes[NUMBER_OF_CLASSES]={"class1","class2","class3","class4","class5","class6"}; 00090 int targetExposure ; 00091 int emptyTime ; 00092 ////////////////////////////////////////// 00093 int emergencyExit(){ 00094 time_t rawtime; 00095 time ( &rawtime ); 00096 LINFO("...emergencyExit called @%s .", ctime( &rawtime )); 00097 d->pushEvent(std::string("experiment ended at ")+ ctime( &rawtime ) ); 00098 manager.stop(); 00099 return -1; 00100 } 00101 00102 00103 ////////////////////////////////////////// 00104 // Here we collect subjects response 00105 uint getStaticResponse(){ 00106 00107 int c = -1; 00108 int conf = -1 ; 00109 int quit = -1 ; 00110 do{ 00111 // 00112 c = -1 ; 00113 while( c!=49 && c!=50 ){ 00114 c = d->waitForKey(); 00115 d->pushEvent("subject decided to report"); 00116 d->clearScreen() ; 00117 if(c!=49 && c!=50 ){ 00118 d-> displayText("Press 1 for 'yes', 2 for 'no'"); 00119 } 00120 } 00121 if( c == 49){ 00122 d-> displayText("You chose 'yes' press space-bar to confirm"); 00123 } else { 00124 d-> displayText("You chose 'no' press space-bar to confirm"); 00125 } 00126 conf = d-> waitForKey() ; 00127 if( conf == 127){ 00128 quit = d-> waitForKey() ; 00129 if( quit == 127 ){ 00130 emergencyExit() ; 00131 } 00132 } 00133 }while(conf!=32) ; 00134 00135 if( c == 49 ){ 00136 d->pushEvent("positive identification confirmed"); 00137 return 1 ; 00138 } else { 00139 d->pushEvent("negative identification confirmed"); 00140 return 0 ; 00141 } 00142 } 00143 00144 00145 ////////////////////////////////////////// 00146 // Here we collect subjects response 00147 uint getDynamicResponse(int c = -1){ 00148 00149 //d->clearScreen(); 00150 int conf = -1 ; 00151 int quit = -1 ; 00152 do{ 00153 00154 while( c!=49 && c!=50 ){ 00155 d-> displayText("Press 1 for 'yes', 2 for 'no'"); 00156 c = d->waitForKey(); 00157 d->pushEvent("subject decided to report"); 00158 } 00159 if( c == 49){ 00160 d-> displayText("You chose 'yes' press space-bar to confirm"); 00161 } else { 00162 d-> displayText("You chose 'no' press space-bar to confirm"); 00163 } 00164 conf = d-> waitForKey() ; 00165 if( conf == 127){ 00166 quit = d-> waitForKey() ; 00167 if( quit == 127 ){ 00168 emergencyExit() ; 00169 } 00170 } 00171 c = -1 ; 00172 }while(conf!=32) ; 00173 00174 if( c == 49 ){ 00175 d->pushEvent("positive identification confirmed"); 00176 return 1 ; 00177 } else { 00178 d->pushEvent("negative identification confirmed"); 00179 return 0 ; 00180 } 00181 } 00182 00183 ///////////////////////////////////////////// 00184 SDL_Surface *load_image( string filename ) 00185 { 00186 //The image that's loaded 00187 SDL_Surface* loadedImage = NULL; 00188 00189 //The optimized image that will be used 00190 SDL_Surface* optimizedImage = NULL; 00191 00192 //Load the image 00193 loadedImage = IMG_Load( filename.c_str() ); 00194 00195 //If the image loaded 00196 if( loadedImage != NULL ) 00197 { 00198 //Create an optimized image 00199 optimizedImage = SDL_DisplayFormat( loadedImage ); 00200 00201 //Free the old image 00202 SDL_FreeSurface( loadedImage ); 00203 00204 //If the image was optimized just fine 00205 if( optimizedImage != NULL ) 00206 { 00207 //Map the color key 00208 Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF ); 00209 00210 //Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent 00211 SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey ); 00212 } 00213 }else{ 00214 emergencyExit() ; 00215 } 00216 00217 //Return the optimized image 00218 return optimizedImage; 00219 } 00220 /////////////////////////////////// 00221 00222 SDL_Surface *getAFreshSurface(int w , int h){ 00223 00224 SDL_Surface *sur = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 00225 0x00000000, 0x00000000, 0x00000000, 0x00000000); 00226 00227 return sur ; 00228 00229 } 00230 //////////////////////////////////// 00231 00232 template <class T> 00233 string stringify(T &i) 00234 { 00235 ostringstream o ; 00236 o << i ; 00237 return o.str(); 00238 } 00239 00240 /////////////////////////////////// 00241 void dumpSurface(SDL_Surface& surface){ 00242 SDL_FreeSurface( &surface ); 00243 } 00244 ///////////////////////////////////////////// 00245 void apply_surface( int x, int y, SDL_Surface& source, SDL_Surface& destination , SDL_Rect& clip ) 00246 { 00247 //Make a temporary rectangle to hold the offsets 00248 SDL_Rect offset; 00249 00250 //Give the offsets to the rectangle 00251 offset.x = x; 00252 offset.y = y; 00253 00254 //Blit the surface 00255 SDL_BlitSurface( &source, &clip, &destination, &offset ); 00256 } 00257 ///////////////////////////////////////////// 00258 int readTop(ifstream& inFile){ 00259 char ch[1000] ; 00260 while( inFile.getline(ch , 1000) ){ 00261 string line = ch ; 00262 LINFO("reads : %s" , line.c_str()) ; 00263 if( line.compare("end_top") == 0 ) break; 00264 if( line.substr(0,4).compare("skin")==0 ){ 00265 string::size_type position = line.find("=") ; 00266 string skinName = line.substr(0,position) ; 00267 string path = line.substr(position+1) ; 00268 skinFileMap[skinName] = path ; 00269 } 00270 if( line.substr(0,15).compare("target_exposure")==0 ){ 00271 string::size_type position = line.find("="); 00272 char rf[10] ; 00273 strcpy(rf,line.substr(position+1).c_str()); 00274 targetExposure = atoi(rf); 00275 d->pushEvent(line.c_str()); 00276 } 00277 if( line.substr(0,10).compare("empty_time")==0 ){ 00278 string::size_type position = line.find("=") ; 00279 char rf[10] ; 00280 strcpy(rf,line.substr(position+1).c_str()); 00281 emptyTime = atoi(rf); 00282 } 00283 00284 } 00285 return 0 ; 00286 } 00287 ///////////////////////////////////////////// 00288 void showStaticTarget(Matrix& pattern , SDL_Surface* classSkin){ 00289 int pw = classSkin->w; 00290 int ph = classSkin->h ; 00291 SDL_Rect theClip ; 00292 theClip.x = 0 ; 00293 theClip.y = 0 ; 00294 theClip.w = pw ; 00295 theClip.h = pw ; 00296 SDL_Surface* blankSurface = getAFreshSurface(pw*pattern.getNumOfColumns(),pw*pattern.getNumOfRows()); 00297 int nv = ph / pw ; 00298 for( int r = 0 ; r < pattern.getNumOfRows() ; r++){ 00299 for( int c = 0 ; c < pattern.getNumOfColumns() ; c++){ 00300 if( pattern.get(r,c)== 1 ){ 00301 theClip.y = (rand()%nv)*pw ; 00302 apply_surface(c*pw,r*pw, *classSkin , *blankSurface ,theClip) ; 00303 } 00304 } 00305 } 00306 d->clearScreen(); 00307 SDL_Rect offset; 00308 00309 //Give the offsets to the rectangle 00310 offset.x = (d->getWidth() - blankSurface->w) /2; 00311 offset.y = (d-> getHeight() - blankSurface->h) /2; 00312 d->displaySDLSurfacePatch(blankSurface , &offset,NULL , -2,false, true); 00313 d->waitFrames(targetExposure); 00314 SDL_FreeSurface(blankSurface); 00315 theClip.~SDL_Rect(); 00316 } 00317 ///////////////////////////////////////// 00318 void showDynamicTarget(Matrix& pattern , SDL_Surface* classSkin){ 00319 int pw = classSkin->w; 00320 int ph = classSkin->h ; 00321 SDL_Rect theClip ; 00322 theClip.x = 0 ; 00323 theClip.y = 0 ; 00324 theClip.w = pw ; 00325 theClip.h = pw ; 00326 SDL_Surface* blankSurface = getAFreshSurface(pw*pattern.getNumOfColumns(),pw*pattern.getNumOfRows()); 00327 int nv = ph / pw ; 00328 Matrix* phaseMatrix = getARandomMap(pattern.getNumOfRows(),pattern.getNumOfColumns(),nv) ; 00329 int counter = 0 ; 00330 while(counter < targetExposure ){ 00331 for( int r = 0 ; r < pattern.getNumOfRows() ; r++){ 00332 for( int c = 0 ; c < pattern.getNumOfColumns() ; c++){ 00333 if( pattern.get(r,c)== 1 ){ 00334 theClip.y = ((counter+phaseMatrix->get(r,c)) %nv)*pw ; 00335 apply_surface(c*pw,r*pw, *classSkin , *blankSurface ,theClip) ; 00336 } 00337 } 00338 } 00339 00340 00341 SDL_Rect offset; 00342 00343 //Give the offsets to the rectangle 00344 offset.x = (d->getWidth() - blankSurface->w) /2; 00345 offset.y = (d-> getHeight() - blankSurface->h) /2; 00346 d->displaySDLSurfacePatch(blankSurface , &offset,NULL , -2,true, true); 00347 counter++; 00348 } 00349 00350 SDL_FreeSurface(blankSurface); 00351 phaseMatrix->~Matrix(); 00352 theClip.~SDL_Rect(); 00353 } 00354 ///////////////////////////////////////// 00355 uint showDynamicSlide(Matrix& theMap , map<string,SDL_Surface*>& cmap ){ 00356 int cs = theMap.getNumOfColumns(); 00357 int rs = theMap.getNumOfRows() ; 00358 map<string , int> clipNumMap; 00359 int imageWidth = -1 ; 00360 int imageHeigth = -1 ; 00361 int pw = 0 ; 00362 int maxForPhase = 0; 00363 //int sT = 100 ; 00364 for( map<string,SDL_Surface*>:: iterator it = cmap.begin() ; it != cmap.end() ; ++it ){ 00365 string clName = it->first ; 00366 SDL_Surface* surf = it->second; 00367 int numOfClips = (surf->h) / (surf->w); 00368 clipNumMap[clName] = numOfClips; 00369 maxForPhase = max(maxForPhase,numOfClips); 00370 if(imageWidth == -1){ 00371 pw = surf->w ; 00372 imageWidth = theMap.getNumOfColumns()*pw ; 00373 imageHeigth = theMap.getNumOfRows()*pw ; 00374 } 00375 00376 } 00377 Matrix* phaseMatrix = getARandomMap(rs,cs,maxForPhase) ; 00378 00379 SDL_Rect* theClip = new SDL_Rect(); 00380 theClip->x = 0 ; 00381 theClip->y = 0 ; 00382 theClip->w = pw ; 00383 theClip->h = pw ; 00384 // 00385 SDL_Surface* nbg = getAFreshSurface(imageWidth,imageHeigth); 00386 string cname("") ; 00387 int key = -1 ; 00388 int counter = 0 ; 00389 while( key < 0 ){ 00390 for( int r = 0 ; r < rs ; r++){ 00391 for( int c = 0 ; c < cs ; c++){ 00392 switch( theMap.get(r,c) ){ 00393 case 1 : cname = "class1" ;break ; 00394 case 2 : cname = "class2" ; break ; 00395 case 3 : cname = "class3" ; break ; 00396 case 4 : cname = "class4" ; break ; 00397 case 5 : cname = "class5" ; break ; 00398 case 6 : cname = "class6" ; break ; 00399 } 00400 SDL_Surface* csurf = cmap[cname] ; 00401 int y = ( (counter+phaseMatrix->get(r,c)) % clipNumMap[cname])*pw; 00402 theClip->y = y ; 00403 apply_surface(c*pw,r*pw, *csurf , *nbg ,*theClip) ; 00404 } 00405 } 00406 //d->clearScreen(); 00407 SDL_Rect offset; 00408 offset.x = (d->getWidth() - nbg->w) /2; 00409 offset.y = (d-> getHeight() - nbg->h) /2; 00410 d->pushEvent("displaying frame "+ stringify(counter)); 00411 d->displaySDLSurfacePatch(nbg , &offset,NULL , -2,true, true); 00412 counter++; 00413 key = d->checkForKey(); 00414 if( key!=-1 ) { 00415 d->pushEvent("subject decided to report"); 00416 d->clearScreen(); 00417 break ; 00418 } 00419 } 00420 00421 delete phaseMatrix; 00422 delete theClip; 00423 SDL_FreeSurface(nbg); 00424 return key ; 00425 00426 } 00427 00428 ///////////////////////////////////////// 00429 void showStaticSlide(Matrix& theMap , map<string,SDL_Surface*>& cmap ){ 00430 int cs = theMap.getNumOfColumns(); 00431 int rs = theMap.getNumOfRows() ; 00432 map<string , int> clipNumMap; 00433 int imageWidth = -1 ; 00434 int imageHeigth = -1 ; 00435 int pw = 0 ; 00436 00437 for( map<string,SDL_Surface*>:: iterator it = cmap.begin() ; it != cmap.end() ; ++it ){ 00438 string clName = it->first ; 00439 SDL_Surface* surf = it->second; 00440 int numOfClips = (surf->h) / (surf->w); 00441 clipNumMap[clName] = numOfClips; 00442 if(imageWidth == -1){ 00443 pw = surf->w ; 00444 imageWidth = theMap.getNumOfColumns()*pw ; 00445 imageHeigth = theMap.getNumOfRows()*pw ; 00446 00447 } 00448 00449 } 00450 SDL_Rect* theClip = new SDL_Rect(); 00451 theClip->x = 0 ; 00452 theClip->y = 0 ; 00453 theClip->w = pw ; 00454 theClip->h = pw ; 00455 // 00456 SDL_Surface* nbg = getAFreshSurface(imageWidth,imageHeigth); 00457 for( int r = 0 ; r < rs ; r++){ 00458 for( int c = 0 ; c < cs ; c++){ 00459 const int ti = theMap.get(r,c); 00460 string cname = "class"+stringify(ti); 00461 SDL_Surface* csurf = cmap[cname] ; 00462 int y = (rand() % clipNumMap[cname])*pw; 00463 theClip->y = y ; 00464 apply_surface(c*pw,r*pw, *csurf , *nbg ,*theClip) ; 00465 } 00466 } 00467 d->clearScreen(); 00468 SDL_Rect offset; 00469 offset.x = (d->getWidth() - nbg->w) /2; 00470 offset.y = (d-> getHeight() - nbg->h) /2; 00471 d->clearScreen(); 00472 d->pushEvent("displaying the test image"); 00473 d->displaySDLSurfacePatch(nbg , &offset,NULL , -2,false, true); 00474 SDL_FreeSurface(nbg); 00475 delete theClip; 00476 } 00477 ///////////////////////////////////////////// 00478 void doStaticTraining( map<string,SDL_Surface*>& cmap,vector<string>& messages){ 00479 d->pushEvent("training starts") ; 00480 d->displayText("Training Time! Press any key to start"); 00481 d->showCursor(true); 00482 d->waitForKey() ; 00483 ////// 00484 for( uint i = 0 ; i< messages.size() ; i++){ 00485 d->displayText(messages[i]); 00486 d->pushEvent("displayed training message : " + messages[i]); 00487 d->waitFrames(300); 00488 } 00489 00490 ///// 00491 d->pushEvent("training ends"); 00492 //d->pushEvent("Congradulations! You are ready for the real test"); 00493 d->waitFrames(45); 00494 d->displayText("Press any key to start!") ; 00495 d->waitForKey(); 00496 //d->showCursor(false); 00497 } 00498 00499 void doDynamicTraining( map<string,SDL_Surface*>& cmap,vector<string>& messages){ 00500 d->pushEvent("training starts") ; 00501 d->displayText("Training Time! Press any key to start"); 00502 d->showCursor(true); 00503 d->waitForKey() ; 00504 ////// 00505 for( uint i = 0 ; i< messages.size() ; i++){ 00506 d->pushEvent(messages[i]); 00507 } 00508 00509 ///// 00510 d->pushEvent("training ends"); 00511 //d->pushEvent("Congradulations! You are ready for the real test"); 00512 d->waitFrames(45); 00513 d->displayText("Press any key to start!") ; 00514 d->waitForKey(); 00515 d->showCursor(false); 00516 } 00517 ///////////////////////////////////////////// 00518 int readBlock(ifstream& inFile){ 00519 string block_name("") ; 00520 string pattern("") ; 00521 string skin_name("") ; 00522 int px = 0 ; 00523 int py = 0 ; 00524 int rows = 0 ; 00525 int columns = 0 ; 00526 float rf = 1.0f ; 00527 float prb = 0.5f ; 00528 bool staticFlag = true ; 00529 bool pureFlag = true ; 00530 char ch[1000]; 00531 bool trainingFlag = false ; 00532 bool pureFlag = true ; 00533 string trainingMessage("") ; 00534 vector<string>* messages = new vector<string>() ; 00535 vector<string>* exclusionList = new vector<string>(); 00536 float minAccuracy = 0 ; 00537 float minSensitivity = 0 ; 00538 int minPositiveCase = 75; 00539 int maxNumOfTrials = 180 ; 00540 00541 /*let's read attributes of the block*/ 00542 while( inFile.getline(ch , 1000) ){ 00543 string line = ch ; 00544 LINFO("reads : %s" , line.c_str()) ; 00545 00546 if(line.compare("dynamic")==0) { 00547 staticFlag = false ; 00548 } 00549 00550 if(line.compare("mixed")==0) { 00551 pureFlag = false ; 00552 d ->pushEvent("mixed stimuli"); 00553 } 00554 00555 if(line.compare("end_block")==0) { 00556 d -> pushEvent("ended reading block "+ block_name); 00557 break ; 00558 } 00559 if( line.substr(0,10).compare("block_name") == 0 ){ 00560 string::size_type position = line.find("=") ; 00561 block_name = line.substr(position+1) ; 00562 d -> pushEvent("started reading block "+block_name) ; 00563 } 00564 00565 if( line.substr(0,14).compare("target_pattern") == 0 ){ 00566 string::size_type position = line.find("=") ; 00567 pattern = line.substr(position+1) ; 00568 d -> pushEvent("target pattern "+pattern) ; 00569 } 00570 00571 if( line.substr(0,16).compare("excluded_pattern") == 0 ){ 00572 string::size_type position = line.find("=") ; 00573 string exPattern = line.substr(position+1); 00574 exclusionList->push_back(exPattern ) ; 00575 d -> pushEvent("excluded pattern "+exPattern) ; 00576 } 00577 00578 if( line.substr(0,4).compare("skin") == 0 ){ 00579 string::size_type position = line.find("=") ; 00580 skin_name = line.substr(position+1) ; 00581 } 00582 00583 if(line.substr(0,2).compare("rf")==0){ 00584 string::size_type position = line.find("="); 00585 char x[10] ; 00586 strcpy(x,line.substr(position+1).c_str()); 00587 rf = atof(x); 00588 } 00589 if(line.substr(0,11).compare("probability")==0){ 00590 string::size_type position = line.find("="); 00591 char rf[10] ; 00592 strcpy(rf,line.substr(position+1).c_str()); 00593 prb = atof(rf); 00594 } 00595 if(line.substr(0,2).compare("px")==0){ 00596 string::size_type position = line.find("="); 00597 char rf[10] ; 00598 strcpy(rf,line.substr(position+1).c_str()); 00599 px = atoi(rf); 00600 } 00601 if(line.substr(0,2).compare("py")==0){ 00602 string::size_type position = line.find("="); 00603 char rf[10] ; 00604 strcpy(rf,line.substr(position+1).c_str()); 00605 py = atoi(rf); 00606 } 00607 if(line.substr(0,2).compare("rs")==0){ 00608 string::size_type position = line.find("="); 00609 char rf[10] ; 00610 strcpy(rf,line.substr(position+1).c_str()); 00611 rows = atoi(rf); 00612 } 00613 if(line.substr(0,2).compare("cs")==0){ 00614 string::size_type position = line.find("="); 00615 char rf[10] ; 00616 strcpy(rf,line.substr(position+1).c_str()); 00617 columns = atoi(rf); 00618 } 00619 if(line.substr(0,16).compare("minimum_positive")==0){ 00620 string::size_type position = line.find("="); 00621 char rf[10] ; 00622 strcpy(rf,line.substr(position+1).c_str()); 00623 minPositiveCase = atoi(rf); 00624 } 00625 00626 if(line.substr(0,13).compare("maximum_trial")==0){ 00627 string::size_type position = line.find("="); 00628 char rf[10] ; 00629 strcpy(rf,line.substr(position+1).c_str()); 00630 maxNumOfTrials = atoi(rf); 00631 } 00632 00633 00634 if( line.substr(0,12).compare("min_accuracy")==0 ){ 00635 string::size_type position = line.find("="); 00636 char rf[10] ; 00637 strcpy(rf,line.substr(position + 1 ).c_str()); 00638 minAccuracy = atof(rf); 00639 } 00640 if( line.substr(0,15).compare("min_sensitivity")==0 ){ 00641 string::size_type position = line.find("="); 00642 char rf[10] ; 00643 strcpy(rf,line.substr(position + 1 ).c_str()); 00644 minSensitivity = atof(rf); 00645 } 00646 if( line.substr(0,16).compare("training_message")==0 ){ 00647 string::size_type position = line.find("="); 00648 trainingFlag = true ; 00649 trainingMessage = line.substr(position +1) ; 00650 messages->push_back(trainingMessage); 00651 } 00652 00653 } 00654 00655 /*let's load up the sprites associated with the skin and resize them and store them in a map*/ 00656 map<string,SDL_Surface*>* classesMap = new map<string,SDL_Surface*>(); 00657 for( int i = 0 ; i < 6 ; i++ ){ 00658 string filepath ; 00659 filepath += skinFileMap[skin_name]+"/"+classes[i]+"/ball.png" ; 00660 SDL_Surface* tmpSurface = load_image(filepath) ; 00661 tmpSurface = SDL_Resize(tmpSurface , rf , 6 ); 00662 (*classesMap)[classes[i]] = tmpSurface; 00663 } 00664 00665 /*now we find all Euclidean transormations of the patten and store them in a vector 00666 in every trial one of these pattens will be used (either included or excluded) 00667 */ 00668 Matrix *rawPattenMatrix = getPattenByString(pattern) ; 00669 vector<Matrix*>* vars = getAllVariations(*rawPattenMatrix); 00670 int vs = vars->size() ; 00671 00672 /*Let's start training the subject*/ 00673 d->displayText("Press any key to start!") ; 00674 d->waitForKey() ; 00675 if( trainingFlag ){ 00676 if( staticFlag ){ 00677 doStaticTraining(*classesMap,*messages) ; 00678 } else { 00679 doDynamicTraining(*classesMap,*messages) ; 00680 } 00681 00682 } 00683 00684 /*the real test starts here and unless the required sensitivity is reached or prbability of having 00685 positive cases it will continue 00686 */ 00687 int positiveCases = 0 ; 00688 vector<int>* experiment = new vector<int>(); 00689 vector<int>* report = new vector<int>(); 00690 float sensitivity = 0.0f; 00691 float accuracy = 0.0f ; 00692 float totalNumOfTrials = 0 ; 00693 do{ 00694 00695 00696 /*here we start different trials and we will have as many as block_size trials*/ 00697 d->clearScreen(); 00698 d->displayText("Please wait!") ; 00699 srand ( time(NULL) ); 00700 int patternChannel = rand()%NUMBER_OF_CLASSES ; 00701 string targetClass = classes[patternChannel]; 00702 srand ( time(NULL) ); 00703 /*here we pick one of the transformed pattern to be used*/ 00704 Matrix *patternMatrix = (*vars)[rand()%vs] ; 00705 vector<Matrix*>* mapsVector ; 00706 bool positiveFalg = true ; 00707 00708 /*here we filp a coin to see if we include the pattern or exclude it*/ 00709 if( rand()%10000 < prb*10000 ){ 00710 00711 if(pureFlag){ 00712 mapsVector = getPureMapsWithExactPatternAndExactChannel(rows,columns,NUMBER_OF_CLASSES , patternChannel+1,*patternMatrix,1,1); 00713 }else{ 00714 mapsVector = getMapsWithExactPattenAndExactChannel(rows,columns,NUMBER_OF_CLASSES , patternChannel+1,*patternMatrix,1,1); 00715 } 00716 00717 00718 /*we keep in mind that we chose to include the target in the board*/ 00719 experiment-> push_back(1) ; 00720 }else{ 00721 mapsVector = getMapsWithExactPattenAndExactChannel(rows,columns,NUMBER_OF_CLASSES , patternChannel+1,*patternMatrix,0,1); 00722 /*we keep in mind that we chose to exclude the target from the board*/ 00723 experiment -> push_back(0) ; 00724 positiveFalg = false ; 00725 } 00726 if( positiveFalg ) positiveCases++ ; 00727 Matrix *map = (*mapsVector)[0] ; 00728 d->pushEvent("class picked : " + targetClass) ; 00729 d->pushEvent("pattern picked : "+patternMatrix->toFormattedString()) ; 00730 d->pushEvent("map picked :" +map->toFormattedString()); 00731 00732 /*now that we have picked the target patten and the board map let's start showing the 00733 target 00734 */ 00735 d->clearScreen(); 00736 d->pushEvent("started showing target image"); 00737 if( staticFlag ){ 00738 showStaticTarget(*patternMatrix,(*classesMap)[targetClass]) ; 00739 } else { 00740 showDynamicTarget(*patternMatrix,(*classesMap)[targetClass]) ; 00741 } 00742 /*we let's delay showing the board after the target*/ 00743 d->pushEvent("started showing blink"); 00744 d->displayFixationBlink(-1, -1, emptyTime/2, 2); 00745 /*now that the target is shown we can show the board*/ 00746 00747 if( staticFlag ){ 00748 showStaticSlide(*map,*classesMap ); 00749 report->push_back(getStaticResponse()); 00750 } else { 00751 int resp = showDynamicSlide(*map,*classesMap); 00752 report->push_back(getDynamicResponse(resp)); 00753 } 00754 00755 00756 /*now that we are done with trials let's do some book keeping and see what was subject's sensitivity and 00757 accuracy 00758 */ 00759 00760 float truePositives = 0.0f ; 00761 float trueNegatives = 0.0f ; 00762 float falsePositives = 0.0f ; 00763 float falseNegatives = 0.0f ; 00764 float positives = 0.0f ; 00765 float negatives = 0.0f ; 00766 vector<int>::size_type trialSize = experiment->size() ; 00767 for( uint i = 0 ; i < trialSize ; i++ ){ 00768 if( (*experiment)[i]==1 && (*report)[i]==1 ) {truePositives++ ; positives++ ; } 00769 if( (*experiment)[i]==1 && (*report)[i]==0 ) {falseNegatives++ ; positives++ ; } 00770 if( (*experiment)[i]==0 && (*report)[i]==1 ) {falsePositives++ ;negatives++ ; } 00771 if( (*experiment)[i]==0 && (*report)[i]==0 ) {trueNegatives++ ; negatives++ ;} 00772 } 00773 if( positives != 0 ){ 00774 sensitivity = truePositives / positives ; 00775 } 00776 totalNumOfTrials = (positives+negatives) ; 00777 accuracy = (truePositives + trueNegatives) / totalNumOfTrials ; 00778 00779 00780 d->pushEvent("positiveCases: "+stringify(positiveCases)+" minPositiveCase:"+stringify(minPositiveCase)); 00781 d->pushEvent("accuracy: "+stringify(accuracy)+" minAccuracy:"+stringify(minAccuracy)) ; 00782 d->pushEvent("sensitivity: "+stringify(sensitivity)+" minSensitivity"+stringify(minSensitivity)); 00783 00784 }while( (sensitivity < minSensitivity || accuracy < minAccuracy || positiveCases < minPositiveCase ) && (totalNumOfTrials <= (float)maxNumOfTrials)); 00785 00786 string reportString("") ; 00787 string experimentString(""); 00788 for(uint i = 0 ; i < experiment->size() ; i++){ 00789 experimentString += stringify((*experiment)[i]) ; 00790 reportString += stringify((*report)[i]) ; 00791 } 00792 d->pushEvent("experiment string :" + experimentString); 00793 d->pushEvent("report string:" + reportString) ; 00794 00795 /*and here we do necessary cleanups before finishing up the block*/ 00796 for( map<string,SDL_Surface*>::iterator it=classesMap->begin() ; it!= classesMap->end() ; ++it){ 00797 SDL_FreeSurface(it->second); 00798 } 00799 delete classesMap; 00800 delete rawPattenMatrix; 00801 delete vars; 00802 delete messages; 00803 delete exclusionList; 00804 d-> displayText("You may take a short break!") ; 00805 d->waitForKey() ; 00806 return 0 ; 00807 } 00808 ///////////////////////////////////////////// 00809 int readprofile(const char* filename){ 00810 ifstream inFile(filename, ios::in); 00811 if (! inFile) 00812 { 00813 LINFO("profile '%s' not found!" , filename); 00814 return -1; 00815 } 00816 00817 char ch[1000]; 00818 while (inFile.getline(ch , 1000)){ 00819 string line = ch; 00820 LINFO("reads : %s", line.c_str()); 00821 if( line.substr(0,11).compare("profilename") == 0 ){ 00822 string::size_type position = line.find("="); 00823 d -> pushEvent("profile "+line.substr(position+1)+" started reading" ) ; 00824 } 00825 if(line.compare("start_top")==0 ) readTop(inFile); 00826 if(line.compare("start_block")==0) readBlock(inFile); 00827 if(programQuit == true) break ; 00828 } 00829 00830 return 0 ; 00831 } 00832 ///////////////////////////////////////////// 00833 00834 00835 extern "C" int main( int argc, char* argv[] ) 00836 00837 { 00838 00839 MYLOGVERB = LOG_INFO; 00840 manager.addSubComponent(d); 00841 nub::soft_ref<EventLog> el(new EventLog(manager)); 00842 manager.addSubComponent(el); 00843 d->setEventLog(el); 00844 // Parse command-line: 00845 if (manager.parseCommandLine(argc, argv,"<profile.prf> <logfileName.psy>", 2, 2)==false) 00846 return(1); 00847 manager.setOptionValString(&OPT_EventLogFileName,manager.getExtraArg(1).c_str() ); 00848 manager.start(); 00849 d->clearScreen() ; 00850 readprofile(manager.getExtraArg(0).c_str()); 00851 d->displayText("Experiment is done! Thanks for participating! ") ; 00852 d->waitForKey() ; 00853 manager.stop(); 00854 return(0) ; 00855 } 00856 00857 #endif // INVT_HAVE_LIBSDL_IMAGE 00858