00001
00012
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 #include "FunctionController.h"
00022
00023 #include "datareps/DataRep.h"
00024 #include "datareps/DataRepFactory.h"
00025 #include "datasrcs/DataSource.h"
00026 #include "datasrcs/TupleCut.h"
00027
00028 #include "graphics/ViewBase.h"
00029
00030 #include "plotters/PlotterBase.h"
00031 #include "plotters/Cut1DPlotter.h"
00032 #include "plotters/Cut2DPlotter.h"
00033 #include "plotters/PlotterFactory.h"
00034
00035 #include "projectors/NTupleProjector.h"
00036
00037 #include <algorithm>
00038 #include <stdexcept>
00039 #include <utility>
00040
00041 #include <cassert>
00042
00043 using std::find;
00044 using std::list;
00045 using std::map;
00046 using std::string;
00047 using std::vector;
00048 using std::make_pair;
00049 using std::pair;
00050
00051 class TupleCut;
00052
00053 CutController * CutController::s_instance = 0;
00054
00055 CutController::CutController ( )
00056 {
00057 }
00058
00059 CutController * CutController::instance ( )
00060 {
00061 if ( s_instance == 0 ) {
00062 s_instance = new CutController ( );
00063 }
00064 return s_instance;
00065 }
00066
00067 Cut1DPlotter *
00068 CutController::
00069 addCut ( PlotterBase * plotter, const std::string & label )
00070 {
00071 vector < string > bindings;
00072 bindings.push_back ( label );
00073 PlotterBase * cut = addCut ( plotter, bindings );
00074
00075 return dynamic_cast < Cut1DPlotter * > ( cut );
00076 }
00077
00078 PlotterBase *
00079 CutController::
00080 addCut( PlotterBase * plotter, std::vector < std::string > & bindings )
00081 {
00082 DisplayController * controller = DisplayController::instance ();
00083 const DataSource * source = controller->getNTuple ( plotter );
00084
00085 PlotterBase * cut_plotter = createCut ( "", source, bindings );
00086 addCut ( cut_plotter, plotter );
00087
00088 return cut_plotter;
00089 }
00090
00091
00095 void CutController::addCut ( PlotterBase * cut_plotter,
00096 PlotterBase * plotter )
00097
00098 {
00099
00100
00101
00102 int index = plotter->activePlotIndex ();
00103 if ( index < 0 )
00104 {
00105 FunctionController * controller = FunctionController::instance ();
00106 index = controller->getUniqueNonFunctionIndex ( plotter );
00107 }
00108 if ( index < 0 ) return;
00109
00110 DataRep * targetrep = plotter->getDataRep ( index );
00111 if ( targetrep -> hasNTupleBindings() == false )
00112 assert ( false );
00113
00114 linkCutAndRep( cut_plotter, targetrep);
00115 }
00116
00117
00118 void CutController::linkCutAndRep( PlotterBase * cut_plotter,
00119 DataRep * targetrep )
00120 {
00121 CutPlotter * plotter = dynamic_cast < CutPlotter * > ( cut_plotter );
00122 assert ( plotter != 0 );
00123
00124 linkCutAndRep ( plotter, targetrep );
00125 }
00126
00127 void
00128 CutController::
00129 linkCutAndRep( CutPlotter * cut_plotter,
00130 DataRep * targetrep )
00131 {
00132 const vector < TupleCut > & cuts = cut_plotter -> getCuts ();
00133 assert ( cuts.empty () == false );
00134
00135 ProjectorBase * projbase = targetrep->getProjector ();
00136 NTupleProjector * projector
00137 = dynamic_cast < NTupleProjector * > ( projbase );
00138 assert ( projector );
00139
00140 for ( unsigned int i = 0; i < cuts.size(); i++ ) {
00141 projector->addCut ( &cuts[i] );
00142 }
00143
00144
00145
00146 cut_plotter->addCutTarget ( targetrep );
00147 targetrep->setDirty ();
00148 }
00149
00150 PlotterBase *
00151 CutController::
00152 createCut ( const std::string & ,
00153 const DataSource * ntuple,
00154 const std::vector < std::string > & bindings,
00155 const Color & color ) const
00156 {
00157 std::string datarepname, plottername;
00158 int ndims = bindings.size();
00159
00160 if( ndims == 1 )
00161 {
00162 datarepname = "Histogram";
00163 plottername = "Cut1DPlotter";
00164 }
00165 else if( ndims == 2 )
00166 {
00167 datarepname = "Color Plot";
00168 plottername = "Cut2DPlotter";
00169 }
00170
00171 DataRepController * controller = DataRepController::instance ();
00172 DataRep * rep = controller->createDataRep ( datarepname,
00173 ntuple,
00174 bindings );
00175 assert( rep != 0 );
00176
00177 PlotterFactory * pfactory = PlotterFactory::instance ();
00178 PlotterBase * pbase = pfactory->create ( plottername );
00179
00180 if( ndims == 1 )
00181 {
00182 Cut1DPlotter * c1dplotter = dynamic_cast < Cut1DPlotter * > ( pbase );
00183 assert( c1dplotter );
00184
00185 c1dplotter->addDataRep ( rep );
00186 c1dplotter -> setNTuple ( ntuple );
00187 c1dplotter -> setAxisBinding ( "X", bindings[0] );
00188 c1dplotter -> setCutRangeFull ();
00189 c1dplotter -> setCutColor ( color );
00190
00191 return c1dplotter;
00192 }
00193 else if( ndims == 2 )
00194 {
00195 Cut2DPlotter * c2dplotter = dynamic_cast < Cut2DPlotter * > ( pbase );
00196 assert( c2dplotter );
00197
00198 c2dplotter -> addDataRep ( rep );
00199 c2dplotter -> setNTuple ( ntuple );
00200 c2dplotter -> setAxisBinding ( "X", bindings[0] );
00201 c2dplotter -> setAxisBinding ( "Y", bindings[1] );
00202 c2dplotter -> setCutRangeFull ();
00203 c2dplotter -> setCutColor ( color );
00204
00205 return c2dplotter;
00206 }
00207
00208 return 0;
00209 }
00210
00211 void CutController::removeCut ( PlotterBase * cplotter,
00212 PlotterBase * plotter )
00213 {
00214 CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( cplotter );
00215
00216 if ( cut_plotter != 0 ) {
00217 DataRep * rep = plotter -> selectedDataRep ();
00218
00219 if ( rep != 0 ) {
00220 cut_plotter -> removeFromTarget ( rep );
00221 setZoomPan ( cut_plotter, Axes::X, false );
00222 }
00223 }
00224 }
00225 void
00226 CutController::
00227 fillCutList ( const std::vector < PlotterBase * > & plotter_list,
00228 vector < CutPlotter * > & cut_list )
00229 {
00230 cut_list.clear ();
00231 vector < PlotterBase * >::const_iterator first = plotter_list.begin();
00232 while ( first != plotter_list.end() ) {
00233 PlotterBase * plotter = *first++;
00234 CutPlotter * cutter = dynamic_cast < CutPlotter * > ( plotter );
00235 if ( cutter != 0 ) {
00236 cut_list.push_back ( cutter );
00237 }
00238 }
00239 }
00240
00241 typedef Observable::ObserverList_t ObserverList_t;
00242
00243 const std::vector < const TupleCut * > &
00244 CutController::
00245 getCutList ( const DataRep * datarep ) const
00246 {
00247 ProjectorBase * pbase = datarep -> getProjector ();
00248 NTupleProjector * projector = dynamic_cast < NTupleProjector * > ( pbase );
00249
00250 if ( projector == 0 ) {
00251 string what ( "CutController::getCutList: ");
00252 what += "DataRep does not have NTupleProjector.";
00253 throw std::logic_error ( what );
00254 }
00255
00256 return projector -> getCutList();
00257 }
00258
00259 void
00260 CutController::
00261 fillCutList ( const DataRep * datarep,
00262 std::vector < PlotterBase * > & cut_list )
00263 {
00264 cut_list.clear ();
00265
00266 const ObserverList_t & objects = datarep -> getObservers ();
00267 ObserverList_t::const_iterator first = objects.begin();
00268
00269 while ( first != objects.end() ) {
00270 const hippodraw::Observer * obj = *first++;
00271 const CutPlotter * plotter = dynamic_cast < const CutPlotter * > ( obj );
00272 if ( plotter != 0 ) {
00273 const DataRep * rep = plotter -> getDataRep ( 0 );
00274 if ( rep != datarep ) {
00275 CutPlotter * cp = const_cast < CutPlotter * > ( plotter );
00276 cut_list.push_back ( cp );
00277 }
00278 }
00279 }
00280 }
00281
00282 void
00283 CutController::
00284 fillCutWeb ( const std::vector < PlotterBase * > & plotters,
00285 std::vector < PlotterBase * > & web )
00286 {
00287 web.clear ();
00288 vector < PlotterBase * > ::const_iterator first = plotters.begin ();
00289
00290 while ( first != plotters.end () ) {
00291 PlotterBase * plotter = *first++;
00292 appendToWeb ( plotter, web );
00293 }
00294 }
00295
00296
00297 void
00298 CutController::
00299 appendToWeb ( PlotterBase * plotter, PlotterList_t & web )
00300 {
00301 PlotterList_t::iterator first = find ( web.begin (), web.end(),
00302 plotter );
00303 if ( first == web.end () ) {
00304 web.push_back ( plotter );
00305 int index = plotter -> activePlotIndex ();
00306 if ( index < 0 ) {
00307 web.clear ();
00308 return;
00309 }
00310 DataRep * rep = plotter -> getDataRep ( index );
00311 vector < PlotterBase * > cut_list;
00312 fillCutList ( rep, cut_list );
00313 if ( cut_list.empty () == false ) {
00314 appendToWeb ( cut_list, web );
00315 }
00316 }
00317 }
00318
00319 void
00320 CutController::
00321 appendToWeb ( CutPlotter * cutter,
00322 PlotterList_t & web )
00323 {
00324 PlotterList_t::iterator first = find ( web.begin(), web.end(),
00325 cutter );
00326 if ( first == web.end () ) {
00327 web.push_back ( cutter );
00328
00329 const list < DataRep * > & targets = cutter -> getCutTargets ();
00330 list < DataRep * > ::const_iterator it = targets.begin ();
00331
00332 while ( it != targets.end () ) {
00333 DataRep * rep = *it++;
00334 PlotterBase * plotter = findPlotter ( rep );
00335 assert ( plotter );
00336 appendToWeb ( plotter, web );
00337 }
00338 }
00339 }
00340
00341 void
00342 CutController::
00343 appendToWeb ( const std::vector < PlotterBase * > & cutters,
00344
00345 PlotterList_t & web )
00346 {
00347 PlotterList_t::const_iterator first = cutters.begin ();
00348 while ( first != cutters.end () ) {
00349 PlotterBase * pb = *first++;
00350 CutPlotter * cutter = dynamic_cast < CutPlotter * > ( pb );
00351 appendToWeb ( cutter, web );
00352 }
00353 }
00354
00355 PlotterBase *
00356 CutController::
00357 findPlotter ( const DataRep * datarep )
00358 {
00359 const PlotterBase * plotter = 0;
00360 const ObserverList_t & objects = datarep -> getObservers ();
00361 ObserverList_t::const_iterator first = objects.begin();
00362
00363 while ( first != objects.end () ) {
00364 const hippodraw::Observer * obj = *first++;
00365 const CutPlotter * cutter = dynamic_cast < const CutPlotter * > ( obj );
00366 if ( cutter != 0 ) {
00367 DataRep * plotter_rep = cutter -> getDataRep ( 0 );
00368 if ( plotter_rep == datarep ) {
00369 plotter = cutter;
00370 break;
00371 }
00372 continue;
00373 }
00374 const XyPlotter * xyplotter = dynamic_cast < const XyPlotter * > ( obj );
00375 if ( xyplotter != 0 ) {
00376 plotter = xyplotter;
00377 break;
00378 }
00379 }
00380
00381 return const_cast < PlotterBase * > ( plotter );
00382 }
00383
00384 void
00385 CutController::
00386 fillTupleCutList ( const std::vector < const ViewBase * > & views,
00387 std::vector < const TupleCut * > & cut_list )
00388 {
00389 cut_list.clear();
00390
00391 #ifdef ITERATOR_MEMBER_DEFECT
00392 std::
00393 #endif
00394 vector < const ViewBase * >::const_iterator first = views.begin ();
00395 while ( first != views.end() ) {
00396 const ViewBase * view = *first++;
00397 PlotterBase * pbase = view->getPlotter ();
00398 Cut1DPlotter * plotter = dynamic_cast < Cut1DPlotter * > ( pbase );
00399 if ( plotter == 0 ) continue;
00400
00401 const vector < TupleCut > & cuts = plotter -> getCuts ();
00402 for ( unsigned int i = 0; i < cuts.size(); i++ ) {
00403 cut_list.push_back ( &cuts[i] );
00404 }
00405 }
00406 }
00407
00408 void
00409 CutController::
00410 connectDataRep ( const std::list < ViewBase * > & targets,
00411 const std::vector < const ViewBase * > & views )
00412 {
00413 #ifdef ITERATOR_MEMBER_DEFECT
00414 std::
00415 #endif
00416 list < ViewBase * > :: const_iterator first = targets.begin ();
00417 while( first != targets.end () )
00418 {
00419 ViewBase * view = *first++;
00420 PlotterBase * plotter = view->getPlotter ();
00421 int number = plotter -> getNumDataReps ();
00422
00423 for( int i = 0; i < number; i++ )
00424 {
00425 DataRep * rep = plotter->getDataRep ( i );
00426
00427 if ( rep->hasNTupleBindings () == false )
00428 continue;
00429
00430 connectDataRep ( rep, views );
00431 }
00432 }
00433 }
00434
00435 void
00436 CutController::
00437 connectDataRep( DataRep * rep,
00438 const std::vector < const ViewBase * > & views )
00439 {
00440 ProjectorBase * pbase = rep->getProjector ();
00441 NTupleProjector * projector = dynamic_cast < NTupleProjector * > ( pbase );
00442
00443 if ( projector == 0 ) return;
00444
00445 const vector < const TupleCut * > & cuts = projector->getCutList ();
00446 if ( cuts.empty() == true ) return;
00447
00448 #ifdef ITERATOR_MEMBER_DEFECT
00449 std::
00450 #endif
00451 vector < const TupleCut * > ::const_iterator first = cuts.begin ();
00452 while ( first != cuts.end() ) {
00453 const TupleCut * cut = *first++;
00454 connectDataRep ( cut, rep, views );
00455 }
00456 }
00457
00458 void
00459 CutController::
00460 connectDataRep ( const TupleCut * cut,
00461 DataRep * rep,
00462 const std::vector < const ViewBase * > & views )
00463 {
00464 #ifdef ITERATOR_MEMBER_DEFECT
00465 std::
00466 #endif
00467 vector < const ViewBase * >::const_iterator first = views.begin();
00468 while ( first != views.end() )
00469 {
00470 const ViewBase * view = *first++;
00471 PlotterBase * pbase = view->getPlotter ();
00472
00473 Cut1DPlotter * plotter = dynamic_cast < Cut1DPlotter * > ( pbase );
00474 if ( plotter == 0 ) continue;
00475
00476 const vector < TupleCut > & cuts = plotter -> getCuts ();
00477 for ( unsigned int i = 0; i < cuts.size(); i++ ) {
00478 if ( &cuts[i] == cut ) {
00479 plotter->addCutTarget ( rep );
00480 }
00481 }
00482 }
00483 }
00484
00485 const vector < PlotterBase * > &
00486 CutController::
00487 getCutList ( const std::vector < PlotterBase * > & plotters,
00488 const DataSource * ntuple ) const
00489 {
00490 DisplayController * dc = DisplayController::instance ();
00491
00492 m_cut_list.clear ();
00493 std::vector < PlotterBase * >::const_iterator it = plotters.begin();
00494
00495 for ( ; it != plotters.end(); ++it )
00496 {
00497 PlotterBase * plotter = *it;
00498 CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( plotter );
00499
00500 if ( cut_plotter != 0 ) {
00501 const DataSource * cut_tuple = dc ->getNTuple ( cut_plotter );
00502 if ( cut_tuple == ntuple ) {
00503 m_cut_list.push_back ( cut_plotter );
00504 }
00505 }
00506 }
00507
00508 return m_cut_list;
00509 }
00510
00511 void CutController::setAxisBinding ( PlotterBase * plotter,
00512 const std::string & axis,
00513 const std::string & label )
00514 {
00515 CutPlotter * cut_plotter = dynamic_cast < CutPlotter * > ( plotter );
00516
00517 if ( cut_plotter != 0 ) {
00518 cut_plotter -> setAxisBinding ( axis, label );
00519 }
00520 }
00521
00522 void
00523 CutController::
00524 setZoomPan ( PlotterBase * cut_plotter,
00525 hippodraw::Axes::Type axis,
00526 bool yes )
00527 {
00528 if ( yes )
00529 m_zoom_pan.push_back ( make_pair( cut_plotter, axis ) );
00530 else
00531 m_zoom_pan.remove ( make_pair( cut_plotter, axis ) );
00532 }
00533
00534 bool
00535 CutController::
00536 isZoomPan ( const PlotterBase * cut_plotter,
00537 hippodraw::Axes::Type axis ) const
00538 {
00539 bool found = false;
00540
00541 list< pair< PlotterBase *, Axes::Type > >::const_iterator iter;
00542
00543 for( iter = m_zoom_pan.begin(); iter != m_zoom_pan.end(); iter++ )
00544 if( iter -> first == cut_plotter && iter -> second == axis )
00545 found = true;
00546
00547 return found;
00548 }