libeblearngui
/home/rex/ebltrunk/tools/libeblearngui/include/datasource_gui.hpp
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_ */