CMS 3D CMS Logo

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