CutController.cxx

Go to the documentation of this file.
00001 
00012 // for truncation warning in debug mode
00013 #ifdef _MSC_VER
00014 #include "msdevstudio/MSconfig.h"
00015 #endif
00016 
00017 #include "CutController.h"
00018 
00019 #include "DisplayController.h"
00020 #include "DataRepController.h"
00021 
00022 #include "datareps/DataRep.h"
00023 #include "datareps/DataRepFactory.h"
00024 #include "datasrcs/DataSource.h"
00025 #include "datasrcs/TupleCut.h"
00026 
00027 #include "graphics/ViewBase.h"
00028 
00029 #include "plotters/PlotterBase.h"
00030 #include "plotters/Cut1DPlotter.h"
00031 #include "plotters/Cut2DPlotter.h"
00032 #include "plotters/PlotterFactory.h"
00033 
00034 #include "projectors/NTupleProjector.h"
00035 
00036 #include <algorithm>
00037 #include <stdexcept>
00038 #include <utility>
00039 
00040 #include <cassert>
00041 
00042 using std::find;
00043 using std::list;
00044 using std::map;
00045 using std::string;
00046 using std::vector;
00047 using std::make_pair;
00048 using std::pair;
00049 using std::logic_error;
00050 using std::runtime_error;
00051 
00052 using namespace hippodraw;
00053 
00054 CutController * CutController::s_instance = 0;
00055 
00056 CutController::CutController ( )
00057 {
00058 }
00059 
00060 CutController * CutController::instance ( )
00061 {
00062   if ( s_instance == 0 ) {
00063     s_instance = new CutController ( );
00064   }
00065   return s_instance;
00066 }
00067 
00068 Cut1DPlotter *
00069 CutController::
00070 addCut ( PlotterBase * plotter, const std::string & label )
00071 {
00072   vector < string > bindings;
00073   bindings.push_back ( label );
00074   PlotterBase * cut = addCut ( plotter, bindings );
00075 
00076   return dynamic_cast < Cut1DPlotter * > ( cut );
00077 }
00078 
00079 PlotterBase *
00080 CutController::
00081 addCut( PlotterBase * plotter,  std::vector < std::string > & bindings )
00082 {
00083   DisplayController * controller = DisplayController::instance ();
00084   const DataSource * source = controller->getDataSource ( plotter, 0 );
00085   const Color color ( Color::yellow );
00086   CutPlotter * cut_plotter = createCut ( "", source, bindings, color );
00087 
00088   addCut ( cut_plotter, plotter );
00089   
00090   return cut_plotter;
00091 }
00092 
00093 
00094 void
00095 CutController::
00096 addCut ( PlotterBase * src_plotter, PlotterBase * plotter )
00097 {
00098   CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( src_plotter );
00099   if ( cut_plotter == 0 ) { // not a cut
00100     string what ( "Argument was not a cut" );
00101     throw runtime_error ( what );
00102   }
00103 
00104   int index = plotter->activePlotIndex ();
00105   if ( index < 0 ) { // multiple reps are active
00106     unsigned int size = plotter -> getNumDataReps ();
00107     for ( unsigned int i = 0; i < size; i++ ) {
00108       DataRep * targetrep = plotter -> getDataRep ( i );
00109       if ( targetrep -> hasNTupleBindings () ) {
00110         linkCutAndRep ( cut_plotter, targetrep );
00111       }
00112     }
00113   }
00114   else { // single data rep is active
00115     DataRep * targetrep = plotter->getDataRep ( index );
00116     if ( targetrep -> hasNTupleBindings() ) {
00117       linkCutAndRep( cut_plotter, targetrep);
00118     }
00119   }
00120 
00121   CutPlotter * cp = dynamic_cast < CutPlotter * > ( plotter );
00122   if ( cp != 0 ) {
00123     const list < DataRep * > & targets = cp -> getCutTargets ();
00124     list < DataRep * > :: const_iterator first = targets.begin();
00125     while ( first != targets.end () ) {
00126       DataRep * target = *first++;
00127       linkCutAndRep ( cut_plotter, target );
00128     }
00129   }
00130 }
00131 
00132 void
00133 CutController::
00134 addCuts ( const std::vector < PlotterBase * > & cut_list,
00135           PlotterBase * plotter )
00136 {
00137   unsigned int size = cut_list.size ();
00138 
00139   for ( unsigned int i = 0; i < size; i++ ) {
00140     PlotterBase * pb = cut_list[i];
00141     CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( pb );
00142     if ( cut_plotter != plotter ) {
00143       addCut ( cut_plotter, plotter );
00144     }
00145   }
00146 }
00147 
00148 void
00149 CutController::
00150 linkCutAndRep( CutPlotter * cut_plotter,
00151                DataRep * targetrep )
00152 {
00153   const vector < TupleCut > & cuts = cut_plotter -> getCuts ();
00154   assert ( cuts.empty () == false );
00155 
00156   ProjectorBase * projbase = targetrep->getProjector ();
00157   NTupleProjector * projector 
00158     = dynamic_cast < NTupleProjector * > ( projbase );
00159   assert ( projector );
00160 
00161   for ( unsigned int i = 0; i < cuts.size(); i++ ) {
00162     projector->addCut ( &cuts[i] );
00163   }
00164   
00165   cut_plotter->addCutTarget ( targetrep );
00166   targetrep->setDirty ();
00167 }
00168 
00169 CutPlotter * 
00170 CutController::
00171 createCut ( const std::string & ,
00172             const DataSource * ntuple,
00173             const std::vector < std::string > & bindings,
00174             const Color & color ) const
00175 {
00176   std::string datarepname, plottername;
00177   int ndims =  bindings.size();
00178   
00179   if( ndims == 1 )
00180     {
00181       datarepname = "Histogram";     // 1 D DyHistogram (Dynamic Histogram)
00182       plottername = "Cut1DPlotter";  // 1 D cut plotter
00183     }
00184   else if( ndims == 2 )
00185     {
00186       datarepname = "Color Plot";    // 2 D couterpart of DyHistogram
00187       plottername = "Cut2DPlotter";  // 2 D cut plotter
00188     }
00189   
00190   DataRepController * controller = DataRepController::instance ();
00191   DataRep * rep = controller->createDataRep ( datarepname,
00192                                               ntuple,
00193                                               bindings );
00194   assert( rep != 0 );
00195   
00196   PlotterFactory * pfactory = PlotterFactory::instance ();
00197   PlotterBase * pbase = pfactory->create ( plottername );
00198   CutPlotter * plotter = dynamic_cast < CutPlotter * > ( pbase );
00199 
00200   // Add data rep and tuple cut separately.
00201   plotter -> addDataRep ( rep );
00202   plotter -> addTupleCut ( rep );
00203 
00204   plotter -> setNTuple ( ntuple );
00205   plotter -> setAxisBinding ( bindings );
00206   plotter -> setCutRangeFull ();
00207   plotter -> setCutColor ( color );
00208 
00209   return plotter;
00210 }
00211 
00212 void CutController::removeCut ( PlotterBase * cplotter, 
00213                                 PlotterBase * plotter )
00214 {
00215   CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( cplotter );
00216 
00217   if ( cut_plotter != 0 ) {
00218     DataRep * rep = plotter -> selectedDataRep (); 
00219 
00220     if ( rep != 0 ) {
00221       cut_plotter -> removeFromTarget ( rep );
00222       setZoomPan ( cut_plotter, Axes::X, false );
00223     }
00224   }
00225   else { // must be cut for region
00226     DataRep * rep = cplotter -> selectedDataRep ();
00227     rep -> removeCut ();
00228   }
00229 }
00230 
00231 void
00232 CutController::
00233 fillCutList ( const std::vector < PlotterBase * > & plotter_list,
00234               std::vector < CutPlotter * > & cut_list )
00235 {
00236   cut_list.clear ();
00237   vector < PlotterBase * >::const_iterator first = plotter_list.begin();
00238   while ( first != plotter_list.end() ) {
00239     PlotterBase * plotter = *first++;
00240     CutPlotter * cutter = dynamic_cast < CutPlotter * > ( plotter );
00241     if ( cutter != 0 ) {
00242       cut_list.push_back ( cutter );
00243     }
00244   }
00245 }
00246 
00247 const vector < const TupleCut * > &
00248 CutController::
00249 getCutList ( const DataRep * datarep ) const
00250 {
00251   ProjectorBase * pbase = datarep -> getProjector ();
00252   NTupleProjector * projector 
00253     = dynamic_cast < NTupleProjector * > ( pbase );
00254 
00255   if ( projector == 0 ) { // then can't have cuts
00256     string what ( "CutController::getCutList: ");
00257     what += "DataRep does not have NTupleProjector.";
00258     throw std::logic_error ( what );
00259   }
00260 
00261   return projector -> getCutList();
00262 }
00263 
00264 void
00265 CutController::
00266 fillCutList ( const PlotterBase * plotter,
00267               std::vector < PlotterBase * > & cut_list )
00268 {
00269   cut_list.clear();
00270   int reps = plotter -> getNumDataReps ();
00271   for ( int i = 0; i < reps; i++ ) {
00272     const DataRep * rep = plotter -> getDataRep ( i );
00273     vector < PlotterBase * > cuts;
00274     fillCutList ( rep, cuts );
00275     cut_list.insert ( cut_list.end(), cuts.begin(), cuts.end() );
00276   }
00277 }
00278 
00279 void
00280 CutController::
00281 fillCutList ( const DataRep * datarep,
00282               std::vector < PlotterBase * > & cut_list )
00283 {
00284   cut_list.clear ();
00285 
00286   const Observable::ObserverList_t & objects = datarep -> getObservers ();
00287   Observable::ObserverList_t::const_iterator first = objects.begin();
00288 
00289   while ( first != objects.end() ) {
00290     const Observer * obj = *first++;
00291     const CutPlotter * plotter = dynamic_cast < const CutPlotter * > ( obj );
00292     if ( plotter != 0 ) {
00293       const DataRep * rep = plotter -> getDataRep ( 0 );
00294       if ( rep != datarep ) {
00295         CutPlotter * cp = const_cast < CutPlotter * > ( plotter );
00296         cut_list.push_back ( cp );
00297       }
00298     }
00299   }
00300 }
00301 
00302 void
00303 CutController::
00304 fillCutWeb ( const std::vector < PlotterBase * > & plotters,
00305              std::vector < PlotterBase * > & web )
00306 {
00307   web.clear ();
00308   vector < PlotterBase * > ::const_iterator first = plotters.begin ();
00309 
00310   while ( first != plotters.end () ) {
00311     PlotterBase * plotter = *first++;
00312     appendToWeb ( plotter, web );
00313   }
00314 }
00315 
00316 
00317 void
00318 CutController::
00319 appendToWeb ( PlotterBase * plotter, PlotterList_t & web )
00320 {
00321   PlotterList_t::iterator first = find ( web.begin (), web.end(),
00322                                          plotter );
00323   if ( first == web.end () ) {
00324     web.push_back ( plotter );
00325     int index = plotter -> activePlotIndex ();
00326     if ( index < 0 ) {
00327       web.clear ();
00328       return;
00329     }
00330     DataRep * rep = plotter -> getDataRep ( index );
00331     vector < PlotterBase * > cut_list;
00332     fillCutList ( rep, cut_list );
00333     if ( cut_list.empty () == false ) {
00334       appendToWeb ( cut_list, web );
00335     }
00336   }
00337 }
00338 
00339 void
00340 CutController::
00341 appendToWeb ( CutPlotter * cutter,
00342               PlotterList_t & web )
00343 {
00344   PlotterList_t::iterator first = find ( web.begin(), web.end(),
00345                                          cutter );
00346   if ( first == web.end () ) {
00347     web.push_back ( cutter );
00348     // get the targets and make recurive call
00349     const list < DataRep * > & targets = cutter -> getCutTargets ();
00350     list < DataRep * > ::const_iterator it = targets.begin ();
00351 
00352     while ( it != targets.end () ) {
00353       DataRep * rep = *it++;
00354       PlotterBase * plotter = findPlotter ( rep );
00355       assert ( plotter );
00356       appendToWeb ( plotter, web );
00357     }
00358   }
00359 }
00360 
00361 void
00362 CutController::
00363 appendToWeb ( const std::vector < PlotterBase * > & cutters,
00364               PlotterList_t & web )
00365 {
00366   PlotterList_t::const_iterator first = cutters.begin ();
00367   while ( first != cutters.end () ) {
00368     PlotterBase * pb = *first++;
00369     CutPlotter * cutter = dynamic_cast < CutPlotter * > ( pb );
00370     appendToWeb ( cutter, web );
00371   }
00372 }
00373 
00374 PlotterBase *
00375 CutController::
00376 findPlotter ( const DataRep * datarep )
00377 {
00378   const PlotterBase * plotter = 0;
00379   const Observable::ObserverList_t & objects = datarep -> getObservers ();
00380   Observable::ObserverList_t::const_iterator first = objects.begin();
00381 
00382   while ( first != objects.end () ) {
00383     const Observer * obj = *first++;
00384     const CutPlotter * cutter = dynamic_cast < const CutPlotter * > ( obj );
00385     if ( cutter != 0 ) {
00386       DataRep * plotter_rep = cutter -> getDataRep ( 0 );
00387       if ( plotter_rep == datarep ) {
00388         plotter = cutter;
00389         break;
00390       }
00391       continue; 
00392     }
00393     const XyPlotter * xyplotter = dynamic_cast < const XyPlotter * > ( obj );
00394     if ( xyplotter != 0 ) {
00395       plotter = xyplotter;
00396       break;
00397     }
00398   }
00399 
00400   return const_cast < PlotterBase * > ( plotter );
00401 }
00402 
00403 void 
00404 CutController::
00405 fillTupleCutList ( const std::vector < const ViewBase * > & views,
00406                    std::vector < const TupleCut * > & cut_list )
00407 {
00408   cut_list.clear();
00409 
00410 #ifdef ITERATOR_MEMBER_DEFECT
00411   std::
00412 #endif
00413   vector < const ViewBase * >::const_iterator first = views.begin ();
00414   while ( first != views.end() ) {
00415     const ViewBase * view = *first++;
00416     PlotterBase * pbase = view->getPlotter ();
00417     Cut1DPlotter * plotter = dynamic_cast < Cut1DPlotter * > ( pbase );
00418     if ( plotter == 0 ) continue;
00419 
00420     const vector < TupleCut > & cuts = plotter -> getCuts ();
00421     for ( unsigned int i = 0; i < cuts.size(); i++ ) {
00422       cut_list.push_back ( &cuts[i] );
00423     }
00424   }
00425 }
00426 
00427 void 
00428 CutController::
00429 connectDataRep ( const std::list < ViewBase * > & targets,
00430                  const std::vector < const ViewBase * > & views )
00431 {
00432 #ifdef ITERATOR_MEMBER_DEFECT
00433   std::
00434 #endif
00435   list < ViewBase * > :: const_iterator first = targets.begin ();
00436   while( first != targets.end () )
00437     {
00438       ViewBase * view = *first++;
00439       PlotterBase * plotter = view->getPlotter ();
00440       int number = plotter -> getNumDataReps ();
00441 
00442       for( int i = 0; i < number; i++ )
00443         {
00444           DataRep * rep = plotter->getDataRep ( i );
00445           
00446           if ( rep->hasNTupleBindings () == false )
00447             continue;
00448           
00449           connectDataRep ( rep, views );
00450         }
00451     }
00452 }
00453 
00454 void 
00455 CutController::
00456 connectDataRep( DataRep * rep, 
00457                 const std::vector < const ViewBase * > & views )
00458 {
00459   ProjectorBase * pbase = rep->getProjector ();
00460   NTupleProjector * projector 
00461     = dynamic_cast < NTupleProjector * > ( pbase );
00462 
00463   if ( projector == 0 ) return; // no cuts possible.
00464 
00465   const vector < const TupleCut * > & cuts = projector->getCutList ();
00466   if ( cuts.empty() == true ) return;
00467 
00468 #ifdef ITERATOR_MEMBER_DEFECT
00469   std::
00470 #endif
00471     vector < const TupleCut * > ::const_iterator first = cuts.begin ();
00472   while ( first != cuts.end() ) {
00473     const TupleCut * cut = *first++;
00474     connectDataRep ( cut, rep, views );
00475   }
00476 }
00477 
00478 void 
00479 CutController::
00480 connectDataRep ( const TupleCut * cut, 
00481                  DataRep * rep,
00482                  const std::vector < const ViewBase * > & views )
00483 {
00484 #ifdef ITERATOR_MEMBER_DEFECT
00485   std::
00486 #endif
00487     vector < const ViewBase * >::const_iterator first = views.begin();
00488   while ( first != views.end() )
00489     {
00490       const ViewBase * view = *first++;
00491       PlotterBase * pbase = view->getPlotter ();
00492       
00493       Cut1DPlotter * plotter = dynamic_cast < Cut1DPlotter * > ( pbase );
00494       if ( plotter == 0 ) continue;
00495       
00496       const vector < TupleCut > & cuts = plotter -> getCuts ();
00497       for ( unsigned int i = 0; i < cuts.size(); i++ ) {
00498         if ( &cuts[i] == cut ) {
00499           plotter->addCutTarget ( rep );
00500         }
00501       }
00502     }
00503 }
00504 
00505 const vector < PlotterBase * > &
00506 CutController::
00507 getCutList ( const std::vector < PlotterBase * > & plotters,
00508              const DataSource * ntuple ) const
00509 {
00510   DisplayController * dc = DisplayController::instance ();
00511 
00512   m_cut_list.clear ();
00513   std::vector < PlotterBase * >::const_iterator it = plotters.begin();
00514 
00515   for ( ; it != plotters.end(); ++it )
00516     {
00517       PlotterBase * plotter = *it;
00518       CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( plotter );
00519 
00520       if ( cut_plotter != 0 ) {
00521         const DataSource * cut_tuple = dc ->getDataSource ( cut_plotter, 0 );
00522         if ( cut_tuple == ntuple ) {
00523           m_cut_list.push_back ( cut_plotter );
00524         }
00525       }
00526     }
00527   
00528   return m_cut_list;
00529 }
00530 
00531 void
00532 CutController::
00533 setZoomPan ( PlotterBase * cut_plotter, Axes::Type axis, bool yes )
00534 {
00535   if ( yes ) 
00536     m_zoom_pan.push_back ( make_pair( cut_plotter, axis ) );
00537   else  // no
00538     m_zoom_pan.remove ( make_pair( cut_plotter, axis ) );
00539 }
00540 
00541 bool
00542 CutController::
00543 isZoomPan ( const PlotterBase * cut_plotter,
00544             Axes::Type axis ) const
00545 {
00546   bool found = false;
00547   
00548   list< pair< PlotterBase *, Axes::Type > >::const_iterator iter; 
00549     
00550   for( iter = m_zoom_pan.begin(); iter != m_zoom_pan.end(); iter++ )
00551     if( iter -> first  == cut_plotter && iter -> second == axis )
00552       found = true;
00553   
00554   return found;
00555 }
00556 
00557 void
00558 CutController::
00559 fillAcceptedRows ( std::vector < bool > & acceptArray,
00560                    const DataSource * source,
00561                    const std::vector < const TupleCut * > & cut_list )
00562 {
00563   acceptArray.clear ();
00564 
00565   std::size_t size = source -> rows ();
00566   acceptArray.reserve ( size );
00567 
00568   std::size_t num_cuts = cut_list.size ();
00569   for ( unsigned int i = 0; i < size; i++ )
00570     {
00571       // If cut is not selected, default is accept.
00572       bool accept = true;
00573 
00574       // Check all the cuts.
00575       for ( unsigned int j = 0; j < num_cuts; j++ ) 
00576         {
00577           const TupleCut * tc = cut_list[j];
00578           accept = tc -> acceptRow ( source, i );
00579           if (!accept) break;
00580         }
00581 
00582       acceptArray.push_back ( accept );
00583     }
00584 }
00585 
00586 template < typename T >
00587 class dequal {
00588   T val;
00589 public:
00590   dequal ( const T &x ){ val = x; }
00591   bool operator == ( const T & y ) const { return val - y < 1.0;}
00592 };
00593 
00594 bool operator == ( const double & x,
00595                    const dequal<double> & d )
00596 {
00597   return d == x;
00598 }
00599 
00600 void
00601 CutController::
00602 createIdCut ( const DataSource * source, DataSource * dest )
00603 {
00604   const string colname = source -> getLabelAt( 0 );
00605   const vector < double > & destcol = dest -> getColumn ( colname );
00606   const vector < double > & srccol = source -> getColumn ( 0 );
00607   const string colname_cut = colname + "_cut";
00608   std::size_t dest_size = dest -> rows ();
00609   vector < double > dest_cut ( dest_size, 0. );
00610   for ( std::size_t i = 0; i < srccol.size (); i++ ) {
00611     const double & value = srccol[i];
00612     vector < double > ::const_iterator first 
00613       = find ( destcol.begin(), destcol.end(),
00614                dequal< double> ( value ) );
00615     std::size_t d = distance ( destcol.begin(), first );
00616     dest_cut [d] = 1.0;
00617   }
00618   dest -> addColumn ( colname_cut, dest_cut );
00619 }

Generated for HippoDraw Class Library by doxygen