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 #include "Transport/Stimulus2D.H"
00037 #include "Transport/TransportOpts.H"
00038 #include "Component/ModelOptionDef.H"
00039 #include "Image/DrawOps.H"
00040 #include "Image/Normalize.H"
00041 #include "Raster/GenericFrame.H"
00042 #include "Util/StringConversions.H"
00043 #include "Util/StringUtil.H"
00044 #include "Util/SimTime.H"
00045 #include <fstream>
00046
00047 const ModelOptionDef OPT_Stimulus2DRadius =
00048 { MODOPT_ARG(int), "Stimulus2DRadius", &MOC_INPUT, OPTEXP_CORE,
00049 "The radius of the point to be drawn when reading from a stimulus "
00050 "2D file (.stim)",
00051 "stim2d-radius", '\0', "<integer>", "1" };
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 Stimulus2D::Stimulus2D(OptionManager& mgr,
00074 const std::string& descrName,
00075 const std::string& tagName) :
00076 FrameIstream(mgr, descrName, tagName),
00077 itsRadius(&OPT_Stimulus2DRadius, this),
00078 itsStim(), itsSR(SimTime::ZERO()), itsT(SimTime::ZERO()), itsDims(0,0)
00079 { };
00080
00081
00082 void Stimulus2D::setConfigInfo(const std::string& fileName)
00083 {
00084
00085 std::ifstream *itsFile;
00086 itsFile = new std::ifstream(fileName.c_str());
00087
00088
00089 if (itsFile->is_open() == false)
00090 LFATAL("Cannot open '%s' for reading",fileName.c_str());
00091
00092
00093 std::string line;
00094 int linenum = 0;
00095 while (!itsFile->eof())
00096 {
00097 getline(*itsFile, line);
00098 ++linenum;
00099 }
00100 itsFile->clear();
00101 itsFile->seekg(0,std::ios_base::beg);
00102 linenum -= 3;
00103
00104
00105 if (getline(*itsFile, line) < 0)
00106 LFATAL("Bad Format '%s'",fileName.c_str());
00107 itsSR = SimTime(SimTime::SECS(fromStr<double>(line)));
00108 LINFO("Period:%3.8f",itsSR.secs());
00109
00110
00111 if (getline(*itsFile, line) < 0)
00112 LFATAL("Bad Format '%s'",fileName.c_str());
00113 std::vector<std::string> tmptok;
00114 split(line, "x", std::back_inserter(tmptok));
00115 if (tmptok.size() < 2)
00116 LFATAL("Bad Format '%s', Screen size", fileName.c_str());
00117
00118
00119 itsDims = Dims(fromStr<int>(tmptok[0]),
00120 fromStr<int>(tmptok[1]));
00121 LINFO("Image Size: %dx%d",itsDims.w(),itsDims.h());
00122
00123 std::streampos strpos = itsFile->tellg();
00124
00125 getline(*itsFile, line);
00126
00127 std::vector<std::string> tok;
00128 split(line," ", std::back_inserter(tok));
00129
00130 if ((tok.size() % 3) != 0)
00131 LFATAL("Error parsing '%s', line %d only %d columns",
00132 fileName.c_str(), 3, (int)tok.size());
00133
00134
00135 const int numstims = tok.size();
00136 itsStim = Image<float>(numstims,linenum,ZEROS);
00137 itsFile->seekg(strpos);
00138
00139
00140 linenum = 0;
00141 while (!itsFile->eof())
00142 {
00143
00144 getline(*itsFile, line);
00145
00146
00147 std::vector<std::string> strtok;
00148 split(line, " ", std::back_inserter(strtok));
00149
00150 if ((tok.size() % 3) != 0)
00151 LFATAL("Error parsing '%s', line %d only %d columns",
00152 fileName.c_str(), 3, (int)strtok.size());
00153
00154
00155 for (size_t jj = 0; jj < strtok.size(); jj++)
00156 itsStim.setVal(jj,linenum,fromStr<float>(strtok[jj]));
00157
00158 linenum++;
00159 }
00160 itsFile->close();
00161 }
00162
00163
00164 bool Stimulus2D::setFrameNumber(int n)
00165 {
00166 return skipTo(SimTime::SECS(n * itsSR.secs()));
00167 }
00168
00169
00170 GenericFrameSpec Stimulus2D::peekFrameSpec()
00171 {
00172 if (itsStim.initialized())
00173 {
00174 GenericFrameSpec fs;
00175 fs.nativeType = GenericFrame::GRAY_F32;
00176 fs.videoFormat = VIDFMT_AUTO;
00177 fs.videoByteSwap = false;
00178 fs.dims = getDims();
00179 fs.floatFlags = FLOAT_NORM_PRESERVE;
00180 fs.frameRate = getSR().hertz();
00181 return fs;
00182 }
00183 else
00184 {
00185 LFATAL("Don't be greedy, you can't peek the next frame until"
00186 " you've loaded a file.");
00187 return GenericFrameSpec();
00188 }
00189 }
00190
00191
00192 SimTime Stimulus2D::getNaturalFrameTime() const
00193 {
00194 return getSR();
00195 }
00196
00197
00198 GenericFrame Stimulus2D::readFrame()
00199 {
00200 return GenericFrame( next(itsRadius.getVal()), FLOAT_NORM_PRESERVE);
00201 }
00202
00203
00204 const SimTime Stimulus2D::getTime() const
00205 {
00206 return itsT;
00207 }
00208
00209
00210 const SimTime Stimulus2D::getTotalTime() const
00211 {
00212 double time = ((double)itsStim.getDims().h()-1) * itsSR.secs();
00213 SimTime t(SimTime::SECS(time));
00214 return t;
00215 }
00216
00217
00218 const SimTime Stimulus2D::getSR() const
00219 {
00220 return itsSR;
00221 }
00222
00223
00224 const Dims Stimulus2D::getDims() const
00225 {
00226 return itsDims;
00227 }
00228
00229
00230 Image<float> Stimulus2D::next(const int rad)
00231 {
00232 if (itsStim.initialized())
00233 {
00234 Image<float> retImage(itsDims,ZEROS);
00235 int pos = int(itsT.secs() / itsSR.secs());
00236 for (int jj = 0; jj < itsStim.getDims().w();jj+=3){
00237 int x,y;
00238 float in = itsStim.getVal(jj,pos);
00239 x = (int)itsStim.getVal(jj+1,pos);
00240 y = (int)itsStim.getVal(jj+2,pos);
00241 drawDisk(retImage,Point2D<int>(x,y),rad,in);
00242 }
00243 itsT+=itsSR;
00244 return retImage;
00245 }
00246 else
00247 {
00248 LFATAL("Must call setInputFile before requesting any data!");
00249 return Image<float>();
00250 }
00251 }
00252
00253
00254 bool Stimulus2D::skipTo(const SimTime t)
00255 {
00256 if (t > getTotalTime())
00257 return false;
00258 else
00259 itsT = t;
00260 return true;
00261 }
00262
00263
00264
00265
00266
00267