CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/Fireworks/Core/src/FWTableViewManager.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWTableViewManager
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:
00010 //         Created:  Sun Jan  6 22:01:27 EST 2008
00011 // $Id: FWTableViewManager.cc,v 1.22 2012/06/26 22:13:04 wmtan Exp $
00012 //
00013 
00014 // system include files
00015 #include <iostream>
00016 #include <boost/bind.hpp>
00017 #include <algorithm>
00018 
00019 #include "TEveManager.h"
00020 #include "TClass.h"
00021 #include "Reflex/Base.h"
00022 
00023 // user include files
00024 #include "Fireworks/Core/interface/FWConfiguration.h"
00025 #include "Fireworks/Core/interface/FWTableViewManager.h"
00026 #include "Fireworks/Core/interface/FWEventItem.h"
00027 #include "Fireworks/Core/interface/FWGUIManager.h"
00028 #include "Fireworks/Core/interface/FWColorManager.h"
00029 
00030 #include "Fireworks/Core/interface/FWTypeToRepresentations.h"
00031 #include "Fireworks/Core/interface/fwLog.h"
00032 
00033 
00034 //
00035 // constants, enums and typedefs
00036 //
00037 
00038 //
00039 // static data member definitions
00040 //
00041 
00042 //
00043 // constructors and destructor
00044 //
00045 FWTableViewManager::FWTableViewManager(FWGUIManager* iGUIMgr)
00046 :FWViewManagerBase()
00047 {
00048    FWGUIManager::ViewBuildFunctor f;
00049    f=boost::bind(&FWTableViewManager::buildView,
00050                  this, _1, _2);
00051    iGUIMgr->registerViewBuilder(FWViewType::idToName(FWViewType::kTable), f);
00052 
00053    // ---------- for some object types, we have default table contents ----------
00054    table("reco::GenParticle").
00055    column("pT", 1, "pt").
00056    column("eta", 3).
00057    column("phi", 3).
00058    column("status", TableEntry::INT).
00059    column("pdgId", TableEntry::INT);
00060 
00061    table("reco::Muon").
00062    column("q", TableEntry::INT, "charge").
00063    column("pT", 1, "pt").
00064    column("global", TableEntry::BOOL, "isGlobalMuon").
00065    column("tracker", TableEntry::BOOL, "isTrackerMuon").
00066    column("SA", TableEntry::BOOL, "isStandAloneMuon").
00067    column("calo", TableEntry::BOOL, "isCaloMuon").
00068    column("tr pt", 1, "track().pt()").
00069    column("eta", 3).
00070    column("phi", 3).
00071    column("matches", TableEntry::INT, "numberOfMatches('SegmentArbitration')").
00072    column("d0", 3, "track().d0()").
00073    column("d0 / d0Err", 3, "track().d0() / track().d0Error()");
00074 
00075    table("reco::GsfElectron").
00076    column("q", TableEntry::INT, "charge").
00077    column("pT", 1, "pt").
00078    column("eta", 3).
00079    column("phi", 3).
00080    column("E/p", 3, "eSuperClusterOverP").
00081    column("H/E", 3, "hadronicOverEm").
00082    column("fbrem", 3, "(trackMomentumAtVtx().R() - trackMomentumOut().R()) / trackMomentumAtVtx().R()").
00083    column("dei", 3, "deltaEtaSuperClusterTrackAtVtx()").
00084    column("dpi", 3, "deltaPhiSuperClusterTrackAtVtx()");
00085 
00086    table("reco::Photon").
00087    column("pT", 1, "pt").
00088    column("eta", 3).
00089    column("phi", 3).
00090    column("H/E", 3, "hadronicOverEm");
00091 
00092    table("reco::CaloJet").
00093    column("pT", 1, "pt").
00094    column("eta", 3).
00095    column("phi", 3).
00096    column("ECAL", 1, "p4().E() * emEnergyFraction()").
00097    column("HCAL", 1, "p4().E() * energyFractionHadronic()").
00098    column("emf", 3, "emEnergyFraction()");
00099 
00100    table("reco::Jet").
00101    column("pT", 1, "pt").
00102    column("eta", 3).
00103    column("phi", 3);
00104 
00105    table("reco::MET").
00106    column("et", 1).
00107    column("phi", 3).
00108    column("sumEt", 1).
00109    column("mEtSig", 3);
00110 
00111    table("reco::Track").
00112    column("q", TableEntry::INT, "charge").
00113    column("pT", 1, "pt").
00114    column("eta", 3).
00115    column("phi", 3).
00116    column("d0", 5).
00117    column("d0Err", 5, "d0Error").
00118    column("dz", 5).
00119    column("dzErr", 5, "dzError").
00120    column("vx", 5).
00121    column("vy", 5).
00122    column("vz", 5).
00123    column("pixel hits", TableEntry::INT, "hitPattern().numberOfValidPixelHits()").
00124    column("strip hits", TableEntry::INT, "hitPattern().numberOfValidStripHits()").
00125    column("chi2", 3).
00126    column("ndof", TableEntry::INT);
00127 
00128    table("reco::Vertex").
00129    column("x", 5).
00130    column("xError", 5).
00131    column("y", 5).
00132    column("yError", 5).
00133    column("z", 5).
00134    column("zError", 5).
00135    column("tracks", TableEntry::INT, "tracksSize").
00136    column("chi2", 3).
00137    column("ndof", 3);
00138 
00139    table("CaloTower").
00140    column("emEt", 1).
00141    column("hadEt", 1).
00142    column("et", 1, "Et").
00143    column("eta", 3).
00144    column("phi", 3);
00145    
00146    table("CaloRecHit").
00147    column("id", TableEntry::INT,"detid.rawId").
00148    column("energy",3).
00149    column("time",3).
00150    column("flags",TableEntry::INT,"flags");
00151 }
00152 
00153 FWTableViewManager::~FWTableViewManager()
00154 {
00155 }
00156 
00157 //
00158 // member functions
00159 //
00160 
00173 FWTableViewManager::TableHandle
00174 FWTableViewManager::table(const char *name)
00175 {
00176    TableHandle handle(name, m_tableFormats);
00177    return handle;
00178 }
00179 
00188 FWTableViewManager::TableHandle &
00189 FWTableViewManager::TableHandle::column(const char *name, int precision, const char *expression)
00190 {
00191    TableEntry columnEntry;
00192    columnEntry.name = name;
00193    columnEntry.precision = precision;
00194    columnEntry.expression = expression;
00195    
00196    m_specs[m_name].push_back(columnEntry);
00197    return *this;
00198 }
00199 
00203 FWTableViewManager::TableSpecs::iterator 
00204 FWTableViewManager::tableFormatsImpl(const Reflex::Type &key) 
00205 {
00206    TableSpecs::iterator ret = m_tableFormats.find(key.Name(Reflex::SCOPED));
00207    if (ret != m_tableFormats.end())
00208       return ret;
00209 
00210    // if there is no exact match for the type, try the base classes
00211    for (Reflex::Base_Iterator it = key.Base_Begin(); it != key.Base_End(); ++it) 
00212    {
00213       ret = tableFormatsImpl(it->ToType());
00214       if (ret != m_tableFormats.end()) 
00215          return ret;
00216    }
00217 
00218    return m_tableFormats.end();
00219 }
00220 
00234 FWTableViewManager::TableSpecs::iterator
00235 FWTableViewManager::tableFormats(const Reflex::Type &key) 
00236 {
00237    std::string keyType = key.Name(Reflex::SCOPED);
00238 
00239    TableSpecs::iterator ret = m_tableFormats.find(keyType);
00240 
00241    if (ret != m_tableFormats.end())
00242       return ret;
00243    
00244    ret = tableFormatsImpl(key); // recursive search for base classes
00245 
00246    if (ret != m_tableFormats.end()) 
00247       return ret;
00248 
00249    TableHandle handle = table(keyType.c_str());
00250    for (Reflex::Member_Iterator mi = key.Member_Begin(),
00251                                       me = key.Member_End();
00252         mi != me; ++mi)
00253    {
00254       if (mi->FunctionParameterSize())
00255          continue;
00256       if (!mi->IsPublic())
00257          continue;
00258       if (!mi->IsConst())
00259          continue;
00260       if (mi->TypeOf().ReturnType().Name() == "int")
00261          handle.column(mi->Name().c_str(), TableEntry::INT);
00262       else if (mi->TypeOf().ReturnType().Name() == "bool")
00263          handle.column(mi->Name().c_str(), TableEntry::BOOL);
00264       else if (mi->TypeOf().ReturnType().Name() == "double")
00265          handle.column(mi->Name().c_str(), 5);
00266       else if (mi->TypeOf().ReturnType().Name() == "float")
00267          handle.column(mi->Name().c_str(), 3);
00268    }
00269    return m_tableFormats.find(keyType);
00270 }
00271 
00277 FWTableViewManager::TableSpecs::iterator 
00278 FWTableViewManager::tableFormats(const TClass &key) 
00279 {
00280    return tableFormats(Reflex::Type::ByName(key.GetName()));
00281 }
00282 
00283 class FWViewBase*
00284 FWTableViewManager::buildView(TEveWindowSlot* iParent, const std::string& /*type*/)
00285 {
00286    TEveManager::TRedrawDisabler disableRedraw(gEve);
00287    boost::shared_ptr<FWTableView> view(new FWTableView(iParent, this));
00288    view->setBackgroundColor(colorManager().background());
00289    m_views.push_back(view);
00290    view->beingDestroyed_.connect(boost::bind(&FWTableViewManager::beingDestroyed,
00291                                              this, _1));
00292    return view.get();
00293 }
00294 
00295 void
00296 FWTableViewManager::beingDestroyed(const FWViewBase* iView)
00297 {
00298    for(Views::iterator it = m_views.begin(), itEnd = m_views.end();
00299        it != itEnd;
00300        ++it) 
00301    {
00302       if(it->get() == iView) 
00303       {
00304          m_views.erase(it);
00305          return;
00306       }
00307    }
00308 }
00309 
00310 void
00311 FWTableViewManager::newItem(const FWEventItem* iItem)
00312 {
00313    m_items.push_back(iItem);
00314    iItem->goingToBeDestroyed_.connect(boost::bind(&FWTableViewManager::destroyItem,
00315                                                   this, _1));
00316    notifyViews();
00317 }
00318 
00320 void
00321 FWTableViewManager::notifyViews(void)
00322 {
00323    for(size_t i = 0, e = m_views.size(); i != e; ++i)
00324    { 
00325       FWTableView *view = m_views[i].get();
00326       view->updateItems();
00327       view->dataChanged();
00328    } 
00329 }
00330 
00336 void 
00337 FWTableViewManager::destroyItem(const FWEventItem *iItem)
00338 {
00339    // remove the item from the list
00340    // FIXME: why doesn't it use erase?? Boh...
00341    for (size_t i = 0, e = m_items.size(); i != e; ++i)
00342    {
00343       if (m_items[i] != iItem)
00344          continue;
00345       m_items[i] = 0;
00346    }
00347 
00348    notifyViews();
00349 }
00350 
00355 void
00356 FWTableViewManager::removeAllItems(void)
00357 {
00358    m_items.clear();
00359    notifyViews();
00360 }
00361 
00362 void
00363 FWTableViewManager::modelChangesComing()
00364 {
00365    gEve->DisableRedraw();
00366 }
00367 
00368 void
00369 FWTableViewManager::modelChangesDone()
00370 {
00371    gEve->EnableRedraw();
00372    // tell the views to update their item lists
00373    // FIXME: doesn't this need to call updateItems as well
00374    // and hence notifyViews would be more appropriate?? Boh...
00375    dataChanged();
00376 }
00377 
00379 void
00380 FWTableViewManager::colorsChanged()
00381 {
00382    for(size_t i = 0, e = m_views.size(); i != e; ++i)
00383       m_views[i].get()->resetColors(colorManager());
00384 }
00385 
00386 void
00387 FWTableViewManager::dataChanged()
00388 {
00389    for(size_t i = 0, e = m_views.size(); i != e; ++i)
00390       m_views[i].get()->dataChanged();
00391 }
00392 
00393 FWTypeToRepresentations
00394 FWTableViewManager::supportedTypesAndRepresentations() const
00395 {
00396    FWTypeToRepresentations returnValue;
00397    return returnValue;
00398 }
00399 
00400 const std::string FWTableViewManager::kConfigTypeNames = "typeNames";
00401 
00402 void 
00403 FWTableViewManager::addTo (FWConfiguration &iTo) const
00404 {
00405    // if there are views, it's the job of the first view to store
00406    // the configuration (this is to avoid ordering problems in the
00407    // case of multiple views)
00408    if (!m_views.empty())
00409       return;
00410    // if there are no views, then it's up to us to store the column
00411    // formats.  This is done in addToImpl, which can be called by
00412    // FWTableView as well
00413    addToImpl(iTo);
00414 }
00415      
00416 void 
00417 FWTableViewManager::addToImpl(FWConfiguration &iTo) const
00418 {
00419    FWConfiguration typeNames(1);
00420    char prec[100];
00421 
00422    for (TableSpecs::const_iterator 
00423         iType = m_tableFormats.begin(),
00424         iType_end = m_tableFormats.end();
00425         iType != iType_end; ++iType) 
00426    {
00427       const std::string &typeName = iType->first;
00428       typeNames.addValue(typeName);
00429       FWConfiguration columns(1);
00430       const TableEntries &entries = iType->second;
00431       for (size_t ei = 0, ee = entries.size(); ei != ee; ++ei)
00432       {
00433          const TableEntry &entry = entries[ei];
00434          columns.addValue(entry.name);
00435          columns.addValue(entry.expression);
00436          columns.addValue((snprintf(prec, 100, "%d", entry.precision), prec));
00437       }
00438       iTo.addKeyValue(typeName, columns);
00439    }
00440    iTo.addKeyValue(kConfigTypeNames, typeNames);
00441 }
00442 
00443 void 
00444 FWTableViewManager::setFrom(const FWConfiguration &iFrom)
00445 {
00446    try
00447    {
00448       const FWConfiguration *typeNames = iFrom.valueForKey(kConfigTypeNames);
00449       if (typeNames == 0)
00450       {
00451          fwLog(fwlog::kWarning) << "no table column configuration stored, using defaults\n";
00452          return;
00453       }
00454             
00455       //NOTE: FWTableViewTableManagers hold pointers into m_tableFormats so if we
00456       // clear it those pointers would be invalid
00457       // instead we will just clear the lists and fill them with their new values
00458       //m_tableFormats.clear();
00459       for (FWConfiguration::StringValuesIt 
00460            iType = typeNames->stringValues()->begin(),
00461            iTypeEnd = typeNames->stringValues()->end(); 
00462            iType != iTypeEnd; ++iType) 
00463       {
00464          //std::cout << "reading type " << *iType << std::endl;
00465          const FWConfiguration *columns = iFrom.valueForKey(*iType);
00466          assert(columns != 0);
00467          TableHandle handle = table(iType->c_str());
00468          for (FWConfiguration::StringValuesIt 
00469               it = columns->stringValues()->begin(),
00470               itEnd = columns->stringValues()->end(); 
00471               it != itEnd; ++it) 
00472          {
00473             const std::string &name = *it++;
00474             const std::string &expr = *it++;
00475             int prec = atoi(it->c_str());
00476             handle.column(name.c_str(), prec, expr.c_str());
00477          }
00478       }
00479    } 
00480    catch (...) 
00481    {
00482       // No info about types in the configuration; this is not an
00483       // error, it merely means that the types are handled by the
00484       // first FWTableView.
00485    }
00486 }