libeblearngui
|
00001 /*************************************************************************** 00002 * Copyright (C) 2009 by Pierre Sermanet * 00003 * pierre.sermanet@gmail.com * 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions are met: 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Redistribution under a license not approved by the Open Source 00014 * Initiative (http://www.opensource.org) must display the 00015 * following acknowledgement in all advertising material: 00016 * This product includes software developed at the Courant 00017 * Institute of Mathematical Sciences (http://cims.nyu.edu). 00018 * * The names of the authors may not be used to endorse or promote products 00019 * derived from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 00022 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 00023 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00024 * DISCLAIMED. IN NO EVENT SHALL ThE AUTHORS BE LIABLE FOR ANY 00025 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00026 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00027 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 00028 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 ***************************************************************************/ 00032 00033 #ifndef DATASOURCE_GUI_HPP_ 00034 #define DATASOURCE_GUI_HPP_ 00035 00036 #include <ostream> 00037 #include <iomanip> 00038 00039 #define MAXWIDTH 1000 00040 #define MAXHEIGHT 1000 00041 00042 using namespace std; 00043 00044 namespace ebl { 00045 00047 // labeled_datasource_gui 00048 00049 template <class Tnet, class Tdata, class Tlabel> 00050 labeled_datasource_gui<Tnet, Tdata, Tlabel>:: 00051 labeled_datasource_gui(bool scroll_) 00052 : scroll(scroll_), scroll_added(false), pos(0), display_wid(-1), 00053 _zoom(1), _rmin(0), _rmax(0), _replaced(false),_last_ds(NULL), _ds(NULL) { 00054 } 00055 00056 template <class Tnet, class Tdata, class Tlabel> 00057 labeled_datasource_gui<Tnet, Tdata, Tlabel>::~labeled_datasource_gui() { 00058 if (w && !_replaced) 00059 w->replace_scroll_box_with_copy(this); 00060 } 00061 00062 template <class Tnet, class Tdata, class Tlabel> 00063 void labeled_datasource_gui<Tnet, Tdata, Tlabel>:: 00064 display(labeled_datasource<Tnet, Tdata, Tlabel> &ds, 00065 unsigned int nh, unsigned int nw, 00066 unsigned int h0, unsigned int w0, 00067 double zoom, int wid, const char *wname, bool scrolling, 00068 Tnet rangemin, Tnet rangemax){ 00069 // do a deep copy of dataset only when necessary 00070 if (scroll && !scrolling && (_last_ds != &ds)) { 00071 if (_ds) 00072 delete _ds; 00073 _ds = new labeled_datasource<Tnet, Tdata, Tlabel>(ds); 00074 } 00075 _last_ds = &ds; 00076 // copy parameters 00077 _nh = nh; 00078 _nw = nw; 00079 _h0 = h0; 00080 _w0 = w0; 00081 _zoom = zoom; 00082 _rmin = rangemin; 00083 _rmax = rangemax; 00084 idxdim d = ds.sample_dims(); 00085 bbstate_idx<Tnet> s(d); 00086 idx<Tnet> m = s.x.select(0, 0); 00087 bbstate_idx<Tlabel> lbl; 00088 vector<string*> lblstr; 00089 class_datasource<Tnet,Tdata,Tlabel> *cds = 00090 dynamic_cast<class_datasource<Tnet,Tdata,Tlabel>*>(&ds); 00091 if (cds) 00092 lblstr = cds->get_label_strings(); 00093 _h1 = h0 + nh * (m.dim(0) + 1); 00094 _w1 = w0 + nw * (m.dim(1) + 1); 00095 display_wid = (wid >= 0) ? wid : 00096 (display_wid >= 0) ? display_wid : 00097 new_window((wname ? wname : ds.name()), 00098 nh * (ds.height + 1) - 1, 00099 nw * (ds.width + 1) - 1); 00100 select_window(display_wid); 00101 if (scroll && !scroll_added) { 00102 gui.add_scroll_box((scroll_box*) this); 00103 scroll_added = true; 00104 } 00105 disable_window_updates(); 00106 if (wid == -1) // clear only if we created the window 00107 clear_window(); 00108 gui << white_on_transparent() << gui_only(); 00109 uint k = 0; 00110 ds.seek_begin(); 00111 // loop to reach pos 00112 for (unsigned int p = 0; p < pos; ++p) { 00113 ds.next(); // FIXME add a seek(p) method to ds 00114 k++; 00115 } 00116 unsigned int h = h0, w = w0, sh = 0, sw = 0; 00117 for (unsigned int ih = 0; (ih < nh) && (k < ds.size()); ++ih) { 00118 if (sh + h > MAXHEIGHT) break ; 00119 sh = h; 00120 for (unsigned int iw = 0; (iw < nw) && (k < ds.size()); ++iw) { 00121 if (sw + w > MAXWIDTH) break ; 00122 // draw label if present 00123 ds.fprop_label(lbl); 00124 if ((lblstr.size() > 0) && (lblstr[(int)lbl.x.get()])) 00125 gui << at(h + 1, w + 1) << (lblstr[(int)lbl.x.get()])->c_str(); 00126 else if (ds.labels.order() == 1) // single continuous labels 00127 gui << at(h + 1, w + 1) << setprecision(1) << lbl.x.get(); 00128 // draw data 00129 sw = w; 00130 if (ds.mstate_samples()) { // dataset has multiple states per sample 00131 mstate<bbstate_idx<Tnet> > ms; 00132 ds.fprop_data(ms); 00133 for (uint i = 0; i < ms.size(); ++i) { 00134 idx<Tnet> mm = ms[i].x; 00135 mm = mm.shift_dim(0, 2); 00136 draw_matrix(mm, h, w, _zoom, _zoom, _rmin, _rmax); 00137 w += mm.dim(1) + 1; 00138 } 00139 } else { 00140 ds.fprop_data(s); 00141 //m = s.x.select(0, 0); 00142 m = s.x.shift_dim(0, 2); 00143 draw_matrix(m, h, w, _zoom, _zoom, _rmin, _rmax); 00144 w += m.dim(1) + 1; 00145 } 00146 sw = w - sw; 00147 ds.next(); 00148 k++; 00149 } 00150 w = w0; 00151 h += m.dim(0) + 1; 00152 sh = h - sh; 00153 } 00154 ds.seek_begin(); 00155 enable_window_updates(); 00156 display_controls(); 00157 } 00158 00159 template <class Tnet, class Tdata, class Tlabel> 00160 void labeled_datasource_gui<Tnet, Tdata, Tlabel>:: 00161 display_pickings(labeled_datasource<Tnet, Tdata, Tlabel> &ds, 00162 unsigned int nh, unsigned int nw, 00163 unsigned int h0, unsigned int w0, 00164 double zoom, int wid, const char *wname, bool scrolling, 00165 Tnet rangemin, Tnet rangemax){ 00166 // do a deep copy of dataset only when necessary 00167 if (scroll && !scrolling && (_last_ds != &ds)) { 00168 if (_ds) 00169 delete _ds; 00170 _ds = new labeled_datasource<Tnet, Tdata, Tlabel>(ds); 00171 } 00172 _last_ds = &ds; 00173 // copy parameters 00174 _nh = nh; 00175 _nw = nw; 00176 _h0 = h0; 00177 _w0 = w0; 00178 _zoom = zoom; 00179 _rmin = rangemin; 00180 _rmax = rangemax; 00181 idxdim d = ds.sample_dims(); 00182 idx<Tdata> m = ds.get_sample(0); 00183 bbstate_idx<Tlabel> lbl; 00184 _h1 = h0 + nh * (m.dim(0) + 1); 00185 _w1 = w0 + nw * (m.dim(1) + 1); 00186 display_wid = (wid >= 0) ? wid : 00187 (display_wid >= 0) ? display_wid : 00188 new_window((wname ? wname : ds.name()), 00189 nh * (ds.height + 1) - 1, 00190 nw * (ds.width + 1) - 1); 00191 select_window(display_wid); 00192 if (scroll && !scroll_added) { 00193 gui.add_scroll_box((scroll_box*) this); 00194 scroll_added = true; 00195 } 00196 disable_window_updates(); 00197 if (wid == -1) // clear only if we created the window 00198 clear_window(); 00199 gui << white_on_transparent() << gui_only(); 00200 00201 map<uint,intg> &picks = ds.get_pickings(); 00202 map<uint,intg>::iterator ipicks = picks.begin(); 00203 unsigned int h = h0, w = w0; 00204 uint k = 0; 00205 for (unsigned int ih = 0; (ih < nh) && (k < ds.size()); ++ih) { 00206 for (unsigned int iw = 0; (iw < nw) && (k < ds.size()); ++iw) { 00207 m = ds.get_sample(ipicks->second); 00208 // m = m.shift_dim(0, 2); 00209 ipicks++; 00210 draw_matrix(m, h, w, _zoom, _zoom, (Tdata) _rmin, (Tdata) _rmax); 00211 // // draw label if present 00212 // if ((ds.lblstr) && (ds.lblstr->at((int)lbl.x.get()))) 00213 // gui << at(h + 1, w + 1) << (ds.lblstr->at((int)lbl.x.get()))->c_str(); 00214 // else if (ds.labels.order() == 1) // single continuous labels 00215 // gui << at(h + 1, w + 1) << setprecision(1) << lbl.x.get(); 00216 w += m.dim(1) + 1; 00217 k++; 00218 } 00219 w = w0; 00220 h += m.dim(0) + 1; 00221 } 00222 enable_window_updates(); 00223 display_controls(); 00224 } 00225 00227 // inherited methods to implement for scrolling capabilities 00228 00229 template <class Tnet, class Tdata, class Tlabel> 00230 void labeled_datasource_gui<Tnet, Tdata, Tlabel>::display_next() { 00231 if (next_page()) { 00232 pos = MIN(_ds->size(), pos + _nh * _nw); 00233 display(*_ds, _nh, _nw, _h0, _w0, _zoom, -1, NULL, true, _rmin, _rmax); 00234 } 00235 } 00236 00237 template <class Tnet, class Tdata, class Tlabel> 00238 void labeled_datasource_gui<Tnet, Tdata, Tlabel>::display_previous() { 00239 if (previous_page()) { 00240 pos = std::max((uint) 0, pos - _nh * _nw); 00241 display(*_ds, _nh, _nw, _h0, _w0, _zoom, -1, NULL, true, _rmin, _rmax); 00242 } 00243 } 00244 00245 template <class Tnet, class Tdata, class Tlabel> 00246 unsigned int labeled_datasource_gui<Tnet, Tdata, Tlabel>::max_pages() { 00247 return (unsigned int) (_ds->size() / (_nh * _nw)); 00248 } 00249 00250 // TODO replace with copy constructor 00251 template <class Tnet, class Tdata, class Tlabel> 00252 labeled_datasource_gui<Tnet, Tdata,Tlabel>* 00253 labeled_datasource_gui<Tnet, Tdata, Tlabel>::copy() { 00254 // scroll_box0* labeled_datasource_gui<Tnet, Tdata, Tlabel>::copy() { 00255 //cout << "labeled_datasource_gui::copy."<<endl; 00256 labeled_datasource_gui<Tnet, Tdata, Tlabel> *dscopy = 00257 new labeled_datasource_gui<Tnet, Tdata, Tlabel>(*this); 00258 dscopy->_ds = _ds; 00259 dscopy->_last_ds = _last_ds; 00260 return dscopy; 00261 } 00262 00264 // labeled_pair_datasource_gui 00265 00266 template <class Tnet, class Tdata, class Tlabel> 00267 labeled_pair_datasource_gui<Tnet, Tdata, Tlabel>:: 00268 labeled_pair_datasource_gui(bool scroll_) 00269 : labeled_datasource_gui<Tnet, Tdata, Tlabel>(scroll_), 00270 _last_ds(NULL), _ds(NULL){ 00271 } 00272 00273 template <class Tnet, class Tdata, class Tlabel> 00274 labeled_pair_datasource_gui<Tnet, Tdata, Tlabel>:: 00275 ~labeled_pair_datasource_gui() { 00276 if (this->w) { 00277 this->w->replace_scroll_box_with_copy(this); 00278 this->_replaced = true; 00279 } 00280 } 00281 00282 template <class Tnet, class Tdata, class Tlabel> 00283 void labeled_pair_datasource_gui<Tnet, Tdata, Tlabel>:: 00284 display(labeled_pair_datasource<Tnet, Tdata, Tlabel> &ds, 00285 unsigned int nh, unsigned int nw, 00286 unsigned int h0, unsigned int w0, 00287 double zoom, int wid, const char *wname, bool scrolling, 00288 Tnet rangemin, Tnet rangemax){ 00289 // do a deep copy of dataset only when necessary 00290 if (this->scroll && !scrolling && (_last_ds != &ds)) { 00291 if (_ds) 00292 delete _ds; 00293 _ds = new labeled_pair_datasource<Tnet, Tdata, Tlabel>(ds); 00294 labeled_datasource_gui<Tnet, Tdata,Tlabel>::_ds = _ds; 00295 } 00296 _last_ds = &ds; 00297 // copy parameters 00298 this->_nh = nh; 00299 this->_nw = nw; 00300 this->_h0 = h0; 00301 this->_w0 = w0; 00302 this->_zoom = zoom; 00303 this->_rmin = rangemin; 00304 this->_rmax = rangemax; 00305 idxdim d = ds.sample_dims(); 00306 bbstate_idx<Tnet> in1(d); 00307 bbstate_idx<Tnet> in2(d); 00308 idx<Tnet> m = in1.x.select(0, 0); 00309 bbstate_idx<Tlabel> lbl; 00310 this->_h1 = h0 + nh * (m.dim(0) + 1); 00311 this->_w1 = w0 + nw * (m.dim(1) + 1); 00312 this->display_wid = (wid >= 0) ? wid : 00313 (this->display_wid >= 0) ? this->display_wid : 00314 new_window((wname ? wname : ds.name()), 00315 nh * (ds.height + 1) - 1, 00316 nw * (ds.width + 1) - 1); 00317 select_window(this->display_wid); 00318 if (this->scroll && !this->scroll_added) { 00319 gui.add_scroll_box((scroll_box*) this); 00320 this->scroll_added = true; 00321 } 00322 disable_window_updates(); 00323 if (wid == -1) // clear only if we created the window 00324 clear_window(); 00325 gui << white_on_transparent() << gui_only(); 00326 ds.seek_begin(); 00327 // loop to reach pos 00328 for (unsigned int p = 0; p < this->pos; ++p) 00329 ds.next(); // FIXME add a seek(p) method to ds 00330 unsigned int h = h0, w = w0; 00331 for (unsigned int ih = 0; ih < nh; ++ih) { 00332 for (unsigned int iw = 0; iw < nw; iw += 2) { 00333 ds.fprop(in1, in2, lbl); 00334 ds.next(); 00335 m = in1.x.select(0, 0); 00336 draw_matrix(m, h, w, this->_zoom, this->_zoom, 00337 this->_rmin, this->_rmax); 00338 w += m.dim(1) + 1; 00339 m = in2.x.select(0, 0); 00340 draw_matrix(m, h, w, this->_zoom, this->_zoom, 00341 this->_rmin, this->_rmax); 00342 if ((ds.lblstr) && (ds.lblstr->at((int)lbl.x.get()))) { 00343 string *str = ds.lblstr->at((int)lbl.x.get()); 00344 00345 gui << at(h + 1, w + 1 - (str->size() / 2) * 10) << str->c_str(); 00346 gui << " pair"; 00347 } 00348 w += m.dim(1) + 1; 00349 } 00350 w = w0; 00351 h += m.dim(0) + 1; 00352 } 00353 ds.seek_begin(); 00354 enable_window_updates(); 00355 this->display_controls(); 00356 } 00357 00359 // inherited methods to implement for scrolling capabilities 00360 00361 template <class Tnet, class Tdata, class Tlabel> 00362 void labeled_pair_datasource_gui<Tnet, Tdata, Tlabel>::display_next() { 00363 if (this->next_page()) { 00364 this->pos = MIN(_ds->size(), this->pos + this->_nh * this->_nw); 00365 display(*_ds, this->_nh, this->_nw, this->_h0, this->_w0, this->_zoom, 00366 -1, NULL, true, this->_rmin, this->_rmax); 00367 } 00368 } 00369 00370 template <class Tnet, class Tdata, class Tlabel> 00371 void labeled_pair_datasource_gui<Tnet, Tdata, Tlabel>::display_previous() { 00372 if (this->previous_page()) { 00373 this->pos = std::max((uint) 0, this->pos - this->_nh * this->_nw); 00374 display(*_ds, this->_nh, this->_nw, this->_h0, this->_w0, this->_zoom, 00375 -1, NULL, true, this->_rmin, this->_rmax); 00376 } 00377 } 00378 00379 template <class Tnet, class Tdata, class Tlabel> 00380 unsigned int labeled_pair_datasource_gui<Tnet, Tdata, Tlabel>::max_pages() { 00381 return (unsigned int) (_ds->size() / (this->_nh * (this->_nw / 2))); 00382 } 00383 00384 // TODO replace with copy constructor 00385 template <class Tnet, class Tdata, class Tlabel> 00386 labeled_pair_datasource_gui<Tnet, Tdata,Tlabel>* 00387 labeled_pair_datasource_gui<Tnet, Tdata, Tlabel>::copy() { 00388 // scroll_box0* labeled_datasource_gui<Tnet, Tdata, Tlabel>::copy() { 00389 cout << "labeled_pair_datasource_gui::copy."<<endl; 00390 labeled_pair_datasource_gui<Tnet, Tdata, Tlabel> *dscopy = 00391 new labeled_pair_datasource_gui<Tnet, Tdata, Tlabel>(*this); 00392 ((labeled_datasource_gui<Tnet, Tdata, Tlabel>*)dscopy)->_ds = this->_ds; 00393 ((labeled_datasource_gui<Tnet, Tdata, Tlabel>*)dscopy)->_last_ds 00394 = this->_last_ds; 00395 return dscopy; 00396 } 00397 00398 } // end namespace ebl 00399 00400 #endif /* DATASOURCE_GUI_HPP_ */