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 "ModelNeuron/PlotBuffer.H"
00037 #include "ModelNeuron/SimUnit.H"
00038 #include "Image/DrawOps.H"
00039 #include "Util/StringConversions.H"
00040
00041
00042
00043
00044 PlotBuffer::PlotBuffer()
00045 : itsData(), names(), units(), itsXlabel("Samples"),
00046 itsCount(0), itsChildCount(0), itsTotal(0), itsDepth(0)
00047 {
00048 }
00049
00050
00051 void PlotBuffer::push(const SimUnit& nsm, const uint length,
00052 const uint depth, const bool usedisplayout)
00053 {
00054
00055 if ((itsTotal == 0) || (depth != itsDepth))
00056 {
00057 reset();
00058 getSubInfo(nsm, depth);
00059 ++itsTotal;
00060 itsData.resize(itsTotal);
00061 itsDepth = depth;
00062 }
00063
00064
00065 addData(nsm, length, depth, usedisplayout);
00066 }
00067
00068
00069 void PlotBuffer::addData(const SimUnit& nsm, const uint length,
00070 const uint depth, const bool usedisplayout)
00071 {
00072 if (depth > 0)
00073 for (int i = nsm.numSubs()-1; i >=0; --i)
00074 {
00075 const SimUnit& temp = nsm.getSub(i);
00076 ++itsCount;
00077
00078 addData(temp, length, depth - 1, usedisplayout);
00079 }
00080
00081
00082 if ((uint)itsData[itsChildCount].size() < length)
00083 itsData[itsChildCount].resize(length,0);
00084
00085
00086 const double outval = usedisplayout ? nsm.getDisplayOutput() : nsm.getOutput();
00087 itsData[itsChildCount].push_back(outval);
00088
00089
00090 while ( ((uint)itsData[itsChildCount].size() > length) && (length != 0) )
00091 itsData[itsChildCount].pop_front();
00092
00093 if (itsCount > 0)
00094 {
00095 ++itsChildCount;
00096 --itsCount;
00097 }
00098 else
00099 itsChildCount = 0;
00100 }
00101
00102
00103 void PlotBuffer::reset()
00104 {
00105 itsData.clear();
00106 itsCount = 0;
00107 itsChildCount = 0;
00108 itsTotal = 0;
00109 itsDepth = 0;
00110 }
00111
00112
00113 void PlotBuffer::draw(Image<PixRGB<byte> >& img, const bool clear, const uint w, const uint h, const Range<double>& range)
00114 {
00115 img = draw(clear, w, h, range).render();
00116 }
00117
00118
00119 Layout<PixRGB<byte> > PlotBuffer::draw(const bool clear, const uint w, const uint h, const Range<double>& range)
00120 {
00121 Layout<PixRGB<byte> > layout;
00122 if (itsTotal != 0)
00123 {
00124 if (itsData[0].size() > 1)
00125 {
00126 uint height = h / (uint)itsData.size();
00127 std::vector<std::deque<double> >::reverse_iterator
00128 iter(itsData.rbegin()), end(itsData.rend());
00129
00130 std::vector<std::string>::const_reverse_iterator
00131 nameiter(names.rbegin()), unititer(units.rbegin());
00132
00133 while (iter != end)
00134 {
00135 layout = vcat(layout, linePlot(*iter, w, height, range.min(), range.max(),
00136 nameiter->c_str(), unititer->c_str(), itsXlabel.c_str()));
00137 if (clear)
00138 iter->clear();
00139
00140 ++iter;++nameiter;++unititer;
00141 }
00142 return layout;
00143 }
00144 else
00145 return
00146 Layout<PixRGB<byte> > (Image<PixRGB<byte> >(w,h,ZEROS));
00147 }
00148 return
00149 Layout<PixRGB<byte> > (Image<PixRGB<byte> >(w,h,ZEROS));
00150 }
00151
00152
00153 void PlotBuffer::getSubInfo(const SimUnit& nsm, const uint depth)
00154 {
00155 if (depth > 0)
00156 for (int i = nsm.numSubs() - 1; i >= 0; --i)
00157 {
00158 const SimUnit& temp = nsm.getSub(i);
00159 ++itsTotal;
00160 this->getSubInfo(temp, depth - 1);
00161 }
00162 names.push_back(nsm.getName());
00163 units.push_back(nsm.getUnits());
00164 }
00165
00166
00167 void PlotBuffer::setSamplingRate(const SimTime& time)
00168 {
00169 itsXlabel = PlotBuffer::SimTimeToSI(time);
00170 }
00171
00172
00173 const uint PlotBuffer::getTotal()
00174 {
00175 return itsTotal;
00176 }
00177
00178
00179 std::string PlotBuffer::SimTimeToSI(const SimTime& time)
00180 {
00181 std::string t(time.toString());
00182 int pos,epos;
00183
00184 pos = t.find('.');
00185 epos = t.find('e');
00186
00187
00188 int magnitude = 0;
00189 std::string output;
00190 if (pos != (int)std::string::npos)
00191 {
00192 int cnt = pos + 1;
00193 while (t[cnt] == '0')
00194 ++cnt;
00195 output = t.substr(cnt, t.size() - cnt - 1) + " ";
00196 magnitude = cnt - pos;
00197 }
00198
00199 else if (epos != (int)std::string::npos)
00200 {
00201
00202 output = t.substr(0,epos) + " ";
00203 std::string str = t.substr(epos+2,t.size() - 3 - epos);
00204 magnitude = fromStr<int>(str);
00205 }
00206
00207 switch (magnitude)
00208 {
00209 case 1 :
00210 if (output.compare("1 ") == 0)
00211 output = "";
00212 output += "decisec";
00213 break;
00214 case 2 :
00215 if (output.compare("1 ") == 0)
00216 output = "";
00217 output += "centisec";
00218 break;
00219 case 3 :
00220 if (output.compare("1 ") == 0)
00221 output = "";
00222 output += "ms";
00223 break;
00224 case 4 :
00225 output = "." + output + "ms";
00226 break;
00227 case 5 :
00228 output = ".0" + output + "ms";
00229 break;
00230 case 6 :
00231 if (output.compare("1 ") == 0)
00232 output = "";
00233 output += "microsec";
00234 break;
00235 case 7 :
00236 output = "." + output + "microsec";
00237 break;
00238 case 8 :
00239 output = ".0" + output + "microsec";
00240 break;
00241 case 9 :
00242 if (output.compare("1 ") == 0)
00243 output = "";
00244 output += "nanosec";
00245 break;
00246 default:
00247 output = t.substr(0,t.size() - 1) + " sec";
00248 break;
00249 }
00250 return output;
00251 }
00252
00253
00254
00255
00256
00257 void PlotBufferList::push(const std::vector<const SimUnit*>& nsm,
00258 const uint length, const uint depth,
00259 const bool usedisplayout)
00260 {
00261 if (nsm.size() != itsPb.size())
00262 {
00263 itsPb.clear();
00264 itsPb.resize(nsm.size());
00265 }
00266 std::vector<const SimUnit*>::const_iterator begin(nsm.begin());
00267 std::vector<PlotBuffer>::iterator beginPb(itsPb.begin());
00268 while (begin != nsm.end())
00269 {
00270 beginPb->push(**begin, length, depth, usedisplayout);
00271 ++beginPb; ++begin;
00272 }
00273 }
00274
00275
00276 void PlotBufferList::clear()
00277 {
00278 itsPb.clear();
00279 }
00280
00281
00282 Layout<PixRGB<byte> > PlotBufferList::draw(bool clear, const uint w,
00283 const uint h, const Dims& d, const Range<double>& range)
00284 {
00285 if (itsPb.size() < 1)
00286 {
00287 return Layout<PixRGB<byte> >();
00288 }
00289
00290 Layout<PixRGB<byte> > lay;
00291 if (d == Dims(0,1))
00292 {
00293 const uint height = h / itsPb.size();
00294 std::vector<PlotBuffer>::iterator begin(itsPb.begin());
00295 while (begin != itsPb.end())
00296 lay = vcat(lay, (begin++)->draw(clear, w, height, range));
00297 }
00298 else if (d == Dims(1,0))
00299 {
00300 const uint width = w / itsPb.size();
00301 std::vector<PlotBuffer>::iterator begin(itsPb.begin());
00302 while (begin != itsPb.end())
00303 lay = hcat(lay, (begin++)->draw(clear, width, h, range));
00304 }
00305 else
00306 {
00307 Layout<PixRGB<byte> > layr;
00308 const uint height = h / d.h();
00309 const uint width = w / d.w();
00310 std::vector<PlotBuffer>::iterator begin(itsPb.begin());
00311 for (int r = 0; (r < d.h()) || (begin == itsPb.end()); ++r)
00312 {
00313 for (int c = 0; (c < d.w()) || (begin == itsPb.end()); ++c)
00314 layr = hcat(layr, (begin++)->draw(clear, width, height, range));
00315 lay = vcat(lay,layr);
00316 }
00317 }
00318 return lay;
00319 }
00320
00321
00322 void PlotBufferList::draw(Image<PixRGB<byte> >& img, bool clear,
00323 const uint w, const uint h, const Dims& d, const Range<double>& range)
00324 {
00325 img = draw(clear, w, h, d, range).render();
00326 }
00327
00328
00329 void PlotBufferList::setSamplingRate(const SimTime& time)
00330 {
00331 std::vector<PlotBuffer>::iterator iter(itsPb.begin());
00332 while (iter != itsPb.end())
00333 (iter++)->setSamplingRate(time);
00334 }
00335
00336
00337
00338
00339
00340