CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/Fireworks/Core/src/FWEventItem.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWEventItem
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:
00010 //         Created:  Thu Jan  3 14:59:23 EST 2008
00011 // $Id: FWEventItem.cc,v 1.57 2011/08/20 03:48:40 amraktad Exp $
00012 //
00013 
00014 // system include files
00015 #include <iostream>
00016 #include <algorithm>
00017 #include <exception>
00018 #include <TClass.h>
00019 
00020 // user include files
00021 #include "Fireworks/Core/interface/FWEventItem.h"
00022 #include "DataFormats/FWLite/interface/Event.h"
00023 // Needed to test edm::Event access
00024 // #include "FWCore/Framework/interface/Event.h"
00025 #include "Fireworks/Core/interface/FWModelId.h"
00026 #include "Fireworks/Core/interface/FWModelChangeManager.h"
00027 #include "Fireworks/Core/interface/FWSelectionManager.h"
00028 #include "Fireworks/Core/interface/FWItemAccessorBase.h"
00029 #include "Fireworks/Core/interface/FWEventItemsManager.h"
00030 #include "Fireworks/Core/interface/FWProxyBuilderConfiguration.h"
00031 #include "Fireworks/Core/src/FWGenericHandle.h"
00032 #include "Fireworks/Core/interface/FWGeometry.h"
00033 #include "Fireworks/Core/interface/fwLog.h"
00034 
00035 //
00036 // static data member definitions
00037 //
00038 
00039 int FWEventItem::minLayerValue()
00040 {
00041    return -100;
00042 }
00043 
00044 int FWEventItem::maxLayerValue()
00045 {
00046    return 100;
00047 }
00048 
00049 
00050 //
00051 // constructors and destructor
00052 //
00053 FWEventItem::FWEventItem(fireworks::Context* iContext,
00054                          unsigned int iId,
00055                          boost::shared_ptr<FWItemAccessorBase> iAccessor,
00056                          const FWPhysicsObjectDesc& iDesc,  const FWConfiguration* pbc) :
00057    m_context(iContext),
00058    m_id(iId),
00059    m_name(iDesc.name()),
00060    m_type(iDesc.type()),
00061    m_purpose(iDesc.purpose()),
00062    m_accessor(iAccessor),
00063    m_displayProperties(iDesc.displayProperties()),
00064    m_layer(iDesc.layer()),
00065    m_moduleLabel(iDesc.moduleLabel()),
00066    m_productInstanceLabel(iDesc.productInstanceLabel()),
00067    m_processName(iDesc.processName()),
00068    m_event(0),
00069    m_interestingValueGetter(ROOT::Reflex::Type::ByTypeInfo(*(m_accessor->modelType()->GetTypeInfo())), m_purpose),
00070    m_filter(iDesc.filterExpression(),""),
00071    m_printedErrorThisEvent(false),
00072    m_isSelected(false),
00073    m_proxyBuilderConfig(0)
00074 {
00075    //assert(m_type->GetTypeInfo());
00076    //ROOT::Reflex::Type dataType( ROOT::Reflex::Type::ByTypeInfo(*(m_type->GetTypeInfo())));
00077    //assert(dataType != ROOT::Reflex::Type() );
00078    //
00079    //std::string dataTypeName = dataType.Name(ROOT::Reflex::SCOPED);
00080    //if (dataTypeName[dataTypeName.size() -1] == '>')
00081    //   dataTypeName += " ";
00082    //std::string wrapperName = "edm::Wrapper<" + dataTypeName + ">";
00083    //
00084    //fwLog(fwlog::kDebug) << "Looking for the wrapper name" 
00085    //                    << wrapperName << std::endl;
00086    //m_wrapperType = ROOT::Reflex::Type::ByName(wrapperName);
00087    //
00088    //assert(m_wrapperType != ROOT::Reflex::Type());
00089    if(!m_accessor->isCollection()) {
00090       m_itemInfos.reserve(1);
00091    }
00092    m_filter.setClassName(modelType()->GetName());
00093    m_proxyBuilderConfig = new FWProxyBuilderConfiguration(pbc, this);
00094 }
00095 // FWEventItem::FWEventItem(const FWEventItem& rhs)
00096 // {
00097 //    // do actual copying here;
00098 // }
00099 /*
00100    FWEventItem::~FWEventItem()
00101    {
00102    }
00103  */
00104 //
00105 // assignment operators
00106 //
00107 // const FWEventItem& FWEventItem::operator=(const FWEventItem& rhs)
00108 // {
00109 //   //An exception safe implementation is
00110 //   FWEventItem temp(rhs);
00111 //   swap(rhs);
00112 //
00113 //   return *this;
00114 // }
00115 
00116 //
00117 // member functions
00118 //
00119 void
00120 FWEventItem::setEvent(const edm::EventBase* iEvent)
00121 {
00122    m_printedErrorThisEvent = false;
00123    m_event = iEvent;
00124    m_accessor->reset();
00125    m_itemInfos.clear();
00126    handleChange();
00127 }
00128 
00129 void
00130 FWEventItem::setLabels(const std::string& iModule,
00131                        const std::string& iProductInstance,
00132                        const std::string& iProcess)
00133 {
00134    m_moduleLabel = iModule;
00135    m_productInstanceLabel = iProductInstance;
00136    m_processName = iProcess;
00137    m_accessor->reset();
00138    m_itemInfos.clear();
00139    handleChange();
00140 }
00141 
00142 void
00143 FWEventItem::setName(const std::string& iName)
00144 {
00145    m_name = iName;
00146 }
00147 
00154 void
00155 FWEventItem::setDefaultDisplayProperties(const FWDisplayProperties& iProp)
00156 {
00157    bool visChange = m_displayProperties.isVisible() != iProp.isVisible();
00158    bool colorChanged = m_displayProperties.color() != iProp.color();
00159    bool transparencyChanged = m_displayProperties.transparency() != iProp.transparency();
00160 
00161    if(!visChange && !colorChanged && !transparencyChanged) {
00162       return;
00163    }
00164    //If the default visibility is changed, we want to also change the the visibility of the children
00165    // BUT we want to remember the old visibility so if the visibility is changed again we return
00166    // to the previous state.
00167    // only the visible ones need to be marked as 'changed'
00168    FWChangeSentry sentry(*(changeManager()));
00169 
00170    for(int index=0; index <static_cast<int>(size()); ++index) {
00171       FWDisplayProperties prp = m_itemInfos[index].displayProperties();
00172       bool vis=prp.isVisible();
00173       bool changed = false;
00174       changed = visChange && vis;
00175 
00176       if(colorChanged) {
00177          if(m_displayProperties.color()==prp.color()) {
00178             prp.setColor(iProp.color());
00179             changed = true;
00180          }
00181       }
00182       if (transparencyChanged) {
00183          if(m_displayProperties.transparency() == prp.transparency()) {
00184             prp.setTransparency(iProp.transparency());
00185             changed = true;
00186          }
00187       }
00188       if(changed) {
00189          m_itemInfos[index].m_displayProperties=prp;
00190          FWModelId id(this,index);
00191          changeManager()->changed(id);
00192       }
00193    }
00194    m_displayProperties= iProp;
00195    defaultDisplayPropertiesChanged_(this);
00196 }
00197 
00198 void
00199 FWEventItem::setFilterExpression(const std::string& iExpression)
00200 {
00201    m_filter.setExpression(iExpression);
00202    filterChanged_(this);
00203    runFilter();
00204 }
00205 
00206 void
00207 FWEventItem::runFilter()
00208 {
00209    if(m_accessor->isCollection() && m_accessor->data()) {
00210       //std::cout <<"runFilter"<<std::endl;
00211       FWChangeSentry sentry(*(this->changeManager()));
00212       int size = m_accessor->size();
00213       std::vector<ModelInfo>::iterator itInfo = m_itemInfos.begin();
00214       try {
00215          for(int index = 0; index != size; ++index,++itInfo) {
00216             bool changed = false;
00217             bool wasVisible = itInfo->m_displayProperties.isVisible();
00218             if(not m_filter.passesFilter(m_accessor->modelData(index))) {
00219                itInfo->m_displayProperties.setIsVisible(false);
00220                changed = wasVisible==true;
00221             } else {
00222                itInfo->m_displayProperties.setIsVisible(true);
00223                changed = wasVisible==false;
00224             }
00225             if(changed) {
00226                FWModelId id(this,index);
00227                changeManager()->changed(id);
00228             }
00229          }
00230       } catch( const std::exception& iException) {
00231          //Should log this error
00232          std::cerr <<"Exception occurred while running filter on "<<name()<<"\n"
00233          <<iException.what()<<std::endl;
00234       }
00235    }
00236 }
00237 
00238 void
00239 FWEventItem::unselect(int iIndex) const
00240 {
00241    //check if this is a change
00242    if(bool& sel = m_itemInfos.at(iIndex).m_isSelected) {
00243       sel=false;
00244       FWModelId id(this,iIndex);
00245       selectionManager()->unselect(id);
00246       changeManager()->changed(id);
00247    }
00248 }
00249 void
00250 FWEventItem::select(int iIndex) const
00251 {
00252    bool& sel = m_itemInfos.at(iIndex).m_isSelected;
00253    if(not sel) {
00254       sel = true;
00255       FWModelId id(this,iIndex);
00256       selectionManager()->select(id);
00257       //want to make it obvious what type of object was selected
00258       // therefore we also select the item
00259       const_cast<FWEventItem*>(this)->selectItem();
00260       changeManager()->changed(id);
00261    }
00262 }
00263 void
00264 FWEventItem::toggleSelect(int iIndex) const
00265 {
00266    bool& sel = m_itemInfos.at(iIndex).m_isSelected;
00267    sel = not sel;
00268    FWModelId id(this,iIndex);
00269    if (sel)
00270       selectionManager()->select(id);
00271    else selectionManager()->unselect(id);
00272    changeManager()->changed(id);
00273 }
00274 
00275 void
00276 FWEventItem::setDisplayProperties(int iIndex, const FWDisplayProperties& iProps) const
00277 {
00278    FWDisplayProperties& prop = m_itemInfos.at(iIndex).m_displayProperties;
00279    if(m_displayProperties.isVisible()) {
00280       if( prop
00281           != iProps ) {
00282          prop = iProps;
00283          FWModelId id(this,iIndex);
00284          //selectionManager()->select(id);
00285          changeManager()->changed(id);
00286       }
00287    } else {
00288       if(iProps.isVisible()) {
00289          FWChangeSentry sentry(*(this->changeManager()));
00290          int size = m_accessor->size();
00291          std::vector<ModelInfo>::iterator itInfo = m_itemInfos.begin();
00292          for(int index = 0; index != size; ++index,++itInfo) {
00293             if( itInfo->m_displayProperties.isVisible() ) {
00294                itInfo->m_displayProperties.setIsVisible(false);
00295                FWModelId id(this,index);
00296                changeManager()->changed(id);
00297             }
00298          }
00299          m_itemInfos.at(iIndex).m_displayProperties.setIsVisible(true);
00300          FWModelId id(this,iIndex);
00301          changeManager()->changed(id);
00302          const_cast<FWEventItem*>(this)->m_displayProperties.setIsVisible(true);
00303          //NOTE: need to send out a signal here
00304          defaultDisplayPropertiesChanged_(this);
00305       }
00306    }
00307 }
00308 
00309 void
00310 FWEventItem::moveToFront()
00311 {
00312    assert(0!=m_context->eventItemsManager());
00313    int largest = layer();
00314    for(FWEventItemsManager::const_iterator it = m_context->eventItemsManager()->begin(),
00315           itEnd = m_context->eventItemsManager()->end();
00316        it != itEnd;
00317        ++it) {
00318       if ((*it) && (*it != this) && (*it)->layer() > largest) {
00319          largest= (*it)->layer();
00320       }
00321    }
00322 
00323    if(largest >= layer()) {
00324       m_layer = std::min(largest+1, maxLayerValue());
00325    }
00326 
00327    m_itemInfos.clear();
00328    m_accessor->reset();
00329    handleChange();
00330 }
00331 
00332 void
00333 FWEventItem::moveToBack()
00334 {
00335    assert(0!=m_context->eventItemsManager());
00336    int smallest = layer();
00337    for(FWEventItemsManager::const_iterator it = m_context->eventItemsManager()->begin(),
00338                                            itEnd = m_context->eventItemsManager()->end();
00339        it != itEnd;
00340        ++it) {
00341       if((*it) && (*it != this) && (*it)->layer() < smallest) {
00342          smallest= (*it)->layer();
00343       }
00344    }
00345 
00346    if(smallest <= layer()) {
00347       m_layer = std::max(smallest-1, minLayerValue());
00348    }
00349 
00350    m_itemInfos.clear();
00351    m_accessor->reset();
00352    handleChange();
00353 }
00354 
00355 void
00356 FWEventItem::moveToLayer(int layer)
00357 {
00358    assert(0!=m_context->eventItemsManager());
00359 
00360    m_layer = std::max(std::min(layer, maxLayerValue()), minLayerValue());
00361 
00362    m_itemInfos.clear();
00363    m_accessor->reset();
00364    handleChange();
00365 }
00366 
00367 void
00368 FWEventItem::proxyConfigChanged()
00369 {
00370    m_itemInfos.clear();
00371    m_accessor->reset();
00372    if (m_context->eventItemsManager())
00373       handleChange();
00374 
00375 }
00376 
00377 void 
00378 FWEventItem::handleChange()
00379 {
00380    preItemChanged_(this);
00381    FWChangeSentry sentry(*(this->changeManager()));
00382    //want filter to rerun after all changes have been made
00383    changeManager()->changed(this);
00384    getPrimaryData();
00385    runFilter();
00386 }
00387 
00388 //
00389 // const member functions
00390 //
00391 const void*
00392 FWEventItem::data(const std::type_info& iInfo) const
00393 {
00394    using namespace Reflex;
00395    //At the moment this is a programming error
00396    assert(iInfo == *(m_type->GetTypeInfo()));
00397 
00398    //lookup data if we don't already have it
00399    if (m_accessor->data())
00400       return m_accessor->data();
00401 
00402    m_errorMessage.clear();
00403    if (!m_event)
00404       return m_accessor->data();
00405    
00406    // Retrieve the data from the event.
00407    edm::InputTag tag(m_moduleLabel, m_productInstanceLabel, m_processName);
00408    edm::FWGenericHandle handle(Reflex::Type::ByTypeInfo(iInfo));
00409    try
00410    {
00411       m_event->getByLabel(tag, handle);
00412       setData(*handle);
00413    }
00414    catch (std::exception& iException)
00415    {
00416       if (!m_printedErrorThisEvent) 
00417       {
00418          std::ostringstream s;
00419          s << "Failed to get " << name() << " because \n" <<iException.what();
00420          m_errorMessage=s.str();
00421          m_printedErrorThisEvent = true;
00422       }
00423       return 0;
00424    }
00425    
00426    return m_accessor->data();
00427 }
00428 
00429 void
00430 FWEventItem::setData(const Reflex::Object& iData) const
00431 {
00432    m_accessor->setData(iData);
00433    //std::cout <<"size "<<m_accessor->size()<<std::endl;
00434    if(m_accessor->isCollection()) {
00435       m_itemInfos.reserve(m_accessor->size());
00436       m_itemInfos.resize(m_accessor->size(),ModelInfo(m_displayProperties,false));
00437    } else {
00438       m_itemInfos.push_back(ModelInfo(m_displayProperties,false));
00439    }
00440 }
00441 
00442 void
00443 FWEventItem::getPrimaryData() const
00444 {
00445    //if(0!=m_data) return;
00446    if(0!=m_accessor->data()) return;
00447    this->data(*(m_type->GetTypeInfo()));
00448 }
00449 
00450 const FWDisplayProperties&
00451 FWEventItem::defaultDisplayProperties() const
00452 {
00453    return m_displayProperties;
00454 }
00455 
00456 int
00457 FWEventItem::layer() const
00458 {
00459    return m_layer;
00460 }
00461 
00462 bool
00463 FWEventItem::isInFront() const
00464 {
00465    assert(0!=m_context->eventItemsManager());
00466    for(FWEventItemsManager::const_iterator it = m_context->eventItemsManager()->begin(),
00467                                            itEnd = m_context->eventItemsManager()->end();
00468        it != itEnd;
00469        ++it) {
00470       if((*it) && (*it != this) && (*it)->layer() >= layer()) {
00471          return false;
00472       }
00473    }
00474    return true;
00475 }
00476 
00477 bool
00478 FWEventItem::isInBack() const
00479 {
00480    assert(0!=m_context->eventItemsManager());
00481    for(FWEventItemsManager::const_iterator it = m_context->eventItemsManager()->begin(),
00482                                            itEnd = m_context->eventItemsManager()->end();
00483        it != itEnd;
00484        ++it) {
00485       if((*it) && (*it != this) && (*it)->layer() <= layer()) {
00486          return false;
00487       }
00488    }
00489    return true;
00490 }
00491 
00492 
00493 unsigned int
00494 FWEventItem::id() const
00495 {
00496    return m_id;
00497 }
00498 
00499 const std::string&
00500 FWEventItem::name() const
00501 {
00502    return m_name;
00503 }
00504 
00505 const TClass*
00506 FWEventItem::type() const
00507 {
00508    return m_type;
00509 }
00510 
00511 const std::string&
00512 FWEventItem::purpose() const
00513 {
00514    return m_purpose;
00515 }
00516 
00517 const std::string&
00518 FWEventItem::moduleLabel() const
00519 {
00520    return m_moduleLabel;
00521 }
00522 const std::string&
00523 FWEventItem::productInstanceLabel() const
00524 {
00525    return m_productInstanceLabel;
00526 }
00527 
00528 const std::string&
00529 FWEventItem::processName() const
00530 {
00531    return m_processName;
00532 }
00533 
00534 FWEventItem::ModelInfo
00535 FWEventItem::modelInfo(int iIndex) const
00536 {
00537    getPrimaryData();
00538    if(m_displayProperties.isVisible()) {
00539       return m_itemInfos.at(iIndex);
00540    }
00541    FWDisplayProperties dp(m_itemInfos.at(iIndex).displayProperties());
00542    dp.setIsVisible(false);
00543    ModelInfo t(dp,m_itemInfos.at(iIndex).isSelected());
00544    return t;
00545 }
00546 
00547 size_t
00548 FWEventItem::size() const
00549 {
00550    getPrimaryData();
00551    return m_itemInfos.size();
00552 }
00553 
00554 bool
00555 FWEventItem::isCollection() const
00556 {
00557    return m_accessor->isCollection();
00558 }
00559 
00560 const TClass*
00561 FWEventItem::modelType() const
00562 {
00563    return m_accessor->modelType();
00564 }
00565 
00566 const void*
00567 FWEventItem::modelData(int iIndex) const
00568 {
00569    getPrimaryData();
00570    return m_accessor->modelData(iIndex);
00571 }
00572 
00573 std::string
00574 FWEventItem::modelName(int iIndex) const
00575 {
00576    std::ostringstream s;
00577    size_t lastChar = name().size();
00578    //if name ends in 's' assume it is plural and remove the s for the individual object
00579    if(name()[lastChar-1]=='s') {
00580       --lastChar;
00581    }
00582    s<<name().substr(0,lastChar)<<" "<<iIndex;
00583    return s.str();
00584 }
00585 
00586 bool
00587 FWEventItem::haveInterestingValue() const
00588 {
00589    return true; //m_interestingValueGetter.isValid();
00590 }
00591 
00592  
00593 const std::string&
00594 FWEventItem::modelInterestingValueAsString(int iIndex) const
00595 {
00596    getPrimaryData();
00597    return m_interestingValueGetter.getToolTip(m_accessor->modelData(iIndex));
00598 }
00599 
00600 
00601 const std::string&
00602 FWEventItem::filterExpression() const
00603 {
00604    return m_filter.expression();
00605 }
00606 
00607 void
00608 FWEventItem::destroy() const
00609 {
00610    //NOTE: need to unselect first before announcing destruction
00611    // because some items are listening to the display change and may
00612    // not properly release their connection to that signal after they
00613    // are destroyed via a connection to goingToBeDestroyed_
00614    const_cast<FWEventItem*>(this)->unselectItem();
00615    {
00616       FWChangeSentry sentry(*(changeManager()));
00617    
00618       for(int index=0; index <static_cast<int>(size()); ++index) {
00619          if(m_itemInfos.at(index).m_isSelected) {
00620             FWModelId id(this,index);
00621             selectionManager()->unselect(id);
00622             changeManager()->changed(id);
00623          }
00624       }
00625    }
00626    goingToBeDestroyed_(this);
00627    delete this;
00628 }
00629 
00630 
00631 void
00632 FWEventItem::selectItem()
00633 {
00634    if(!m_isSelected) {
00635       m_isSelected=true;
00636       selectionManager()->selectItem(this);
00637       defaultDisplayPropertiesChanged_(this);
00638    }
00639 }
00640 void
00641 FWEventItem::unselectItem()
00642 {
00643    if(m_isSelected) {
00644       m_isSelected=false;
00645       selectionManager()->unselectItem(this);
00646       defaultDisplayPropertiesChanged_(this);
00647    }
00648 }
00649 void
00650 FWEventItem::toggleSelectItem()
00651 {
00652    m_isSelected = !m_isSelected;
00653    if(m_isSelected) {
00654       selectionManager()->selectItem(this);
00655    }else {
00656       selectionManager()->unselectItem(this);
00657    }
00658    defaultDisplayPropertiesChanged_(this);
00659 }
00660 bool
00661 FWEventItem::itemIsSelected() const
00662 {
00663    return m_isSelected;
00664 }
00665 
00666 bool
00667 FWEventItem::hasError() const {
00668    return !errorMessage().empty();
00669 }
00670 
00671 const std::string&
00672 FWEventItem::errorMessage() const
00673 {
00674    if(m_errorMessage.empty()) {
00675       getPrimaryData();
00676    }
00677    return m_errorMessage;
00678 }
00679 
00680 const FWGeometry* 
00681 FWEventItem::getGeom() const {
00682    return m_context->getGeom();
00683 }
00684 //
00685 // static member functions
00686 //