CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/Fireworks/FWInterface/src/FWFFLooper.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include "Fireworks/FWInterface/interface/FWFFLooper.h"
00003 #include "Fireworks/FWInterface/src/FWFFNavigator.h"
00004 #include "Fireworks/FWInterface/src/FWFFMetadataManager.h"
00005 #include "Fireworks/FWInterface/src/FWFFMetadataUpdateRequest.h"
00006 #include "Fireworks/FWInterface/src/FWPathsPopup.h"
00007 #include "Fireworks/Core/interface/FWConfigurationManager.h"
00008 #include "Fireworks/Core/interface/Context.h"
00009 #include "Fireworks/Core/interface/FWEventItemsManager.h"
00010 #include "Fireworks/Core/src/CmsShowTaskExecutor.h"
00011 #include "Fireworks/Core/interface/CmsShowMainFrame.h"
00012 #include "Fireworks/Core/interface/FWGUIManager.h"
00013 #include "Fireworks/Core/interface/CSGContinuousAction.h"
00014 #include "Fireworks/Core/interface/FWRecoGeom.h"
00015 #include "Fireworks/Core/interface/FWGeometryTableViewManager.h"
00016 #include "Fireworks/Core/interface/fwLog.h"
00017 #include "Fireworks/Geometry/interface/FWRecoGeometry.h"
00018 #include "Fireworks/Geometry/interface/FWRecoGeometryRecord.h"
00019 
00020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00021 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
00022 
00023 #include "FWCore/Framework/interface/EventSetup.h"
00024 #include "FWCore/Framework/interface/ESHandle.h"
00025 #include "FWCore/Framework/interface/ESWatcher.h"
00026 #include "FWCore/Framework/interface/ProcessingController.h"
00027 #include "FWCore/Framework/interface/ScheduleInfo.h"
00028 #include "FWCore/Framework/interface/ModuleChanger.h"
00029 #include "CondFormats/RunInfo/interface/RunInfo.h"
00030 #include "FWCore/Framework/interface/ESTransientHandle.h"
00031 #include "CondFormats/DataRecord/interface/RunSummaryRcd.h"
00032 #include "FWCore/Framework/interface/Run.h"
00033 #include "DataFormats/Common/interface/Handle.h"
00034 #include "DataFormats/Common/interface/ConditionsInEdm.h"
00035 #include "DataFormats/FWLite/interface/LuminosityBlock.h"
00036 #include "DataFormats/Provenance/interface/ModuleDescription.h"
00037 
00038 #include "TROOT.h"
00039 #include "TSystem.h"
00040 #include "TRint.h"
00041 #include "TGLWidget.h"
00042 
00043 #include "TEveManager.h"
00044 #include "TEveEventManager.h"
00045 #include "TEveTrackPropagator.h"
00046 #include "TEveBrowser.h"
00047 #include "TGeoManager.h"
00048 
00049 
00050 namespace
00051 {
00052    class CmsEveMagField : public TEveMagField
00053    {
00054    private:
00055       Float_t fField;
00056       Float_t fFieldMag;
00057 
00058    public:
00059 
00060       CmsEveMagField() : TEveMagField(), fField(-3.8), fFieldMag(3.8) {}
00061       virtual ~CmsEveMagField() {}
00062 
00063       // set current
00064       void SetFieldByCurrent(Float_t avg_current)
00065       {
00066          fField    = -3.8 * avg_current / 18160.0;
00067          fFieldMag = TMath::Abs(fField);
00068       }
00069 
00070       // get field values
00071       virtual Float_t GetMaxFieldMag() const
00072       {
00073          return fFieldMag;
00074       }
00075 
00076       virtual TEveVector GetField(Float_t x, Float_t y, Float_t z) const
00077       {
00078          static const Float_t barrelFac = 1.2 / 3.8;
00079          static const Float_t endcapFac = 2.0 / 3.8;
00080 
00081          const Float_t R    = sqrt(x*x+y*y);
00082          const Float_t absZ = TMath::Abs(z);
00083 
00084          //barrel
00085          if (absZ < 724.0f)
00086          {
00087             //inside solenoid
00088             if (R < 300.0f) return TEveVector(0, 0, fField);
00089 
00090             // outside solinoid
00091             if ((R > 461.0f && R < 490.5f) ||
00092                 (R > 534.5f && R < 597.5f) ||
00093                 (R > 637.0f && R < 700.0f))
00094             {
00095                return TEveVector(0, 0, -fField*barrelFac);
00096             }
00097          } else {
00098             if ((absZ > 724.0f && absZ < 786.0f) ||
00099                 (absZ > 850.0f && absZ < 910.0f) ||
00100                 (absZ > 975.0f && absZ < 1003.0f))
00101             {
00102                const Float_t fac = (z >= 0 ? fField : -fField) * endcapFac / R;
00103                return TEveVector(x*fac, y*fac, 0);
00104             }
00105          }
00106          return TEveVector(0, 0, 0);
00107       }
00108    };
00109 }
00110 
00111 //
00112 // constants, enums and typedefs
00113 //
00114 
00115 //
00116 // static data member definitions
00117 //
00118 
00119 //==============================================================================
00120 // constructors and destructor
00121 //==============================================================================
00122 
00123 FWFFLooper::FWFFLooper(edm::ParameterSet const&ps) 
00124    : CmsShowMainBase(),
00125      m_navigator(new FWFFNavigator(*this)), 
00126      m_metadataManager(new FWFFMetadataManager()),
00127      m_context(new fireworks::Context(changeManager(),
00128                                       selectionManager(),
00129                                       eiManager(),
00130                                       colorManager(),
00131                                       m_metadataManager.get())),
00132      m_Rint(m_appHelper->app()),
00133      m_AllowStep(true),
00134      m_ShowEvent(true),
00135      m_firstTime(true),
00136      m_pathsGUI(0),
00137      m_geomWatcher(this, &FWFFLooper::remakeGeometry)
00138 {
00139    setup(m_navigator.get(), m_context.get(), m_metadataManager.get());
00140 
00141    eiManager()->setContext(m_context.get());
00142 
00143    // By default, we look up geometry and configuration in the workarea, then
00144    // in the release area then in the local directory.  It is also possible to
00145    // override those locations by using the displayConfigurationFilename and
00146    // geometryFilename in the parameterset.
00147    const char *releaseBase = getenv("CMSSW_RELEASE_BASE");
00148    const char *workarea = getenv("CMSSW_BASE");
00149    std::string displayConfigRelFilename = "/src/Fireworks/FWInterface/macros/ffw.fwc";
00150    std::string geometryRelFilename = "/src/Fireworks/FWInterface/data/cmsGeom10.root";
00151 
00152    std::string displayConfigFilename = "ffw.fwc";
00153    std::string geometryFilename;
00154 
00155    if (releaseBase && access((releaseBase + displayConfigFilename).c_str(), R_OK) == 0)
00156       displayConfigFilename = releaseBase + displayConfigRelFilename; 
00157    if (workarea && access((workarea + displayConfigRelFilename).c_str(), R_OK) == 0)
00158       displayConfigFilename = workarea + displayConfigRelFilename;   
00159 
00160    if (releaseBase && access((releaseBase + geometryRelFilename).c_str(), R_OK) == 0)
00161       geometryFilename = releaseBase + geometryRelFilename;
00162    if (workarea && access((workarea + geometryRelFilename).c_str(), R_OK) == 0)
00163       geometryFilename = workarea + geometryRelFilename;
00164 
00165    displayConfigFilename = ps.getUntrackedParameter<std::string>("displayConfigFilename", displayConfigFilename);
00166    geometryFilename = ps.getUntrackedParameter<std::string>("geometryFilename", geometryFilename);
00167 
00168    setGeometryFilename(geometryFilename);
00169    setConfigFilename(displayConfigFilename);
00170 
00171    if( !geometryFilename.empty())
00172    {
00173       loadDefaultGeometryFile();
00174    }
00175 
00176    m_MagField = new CmsEveMagField();
00177 }
00178 
00179 void
00180 FWFFLooper::loadDefaultGeometryFile( void )
00181 {
00182    CmsShowTaskExecutor::TaskFunctor f;
00183    f=boost::bind( &CmsShowMainBase::loadGeometry, this );
00184    startupTasks()->addTask( f );
00185 }
00186 
00187 void
00188 FWFFLooper::attachTo(edm::ActivityRegistry &ar)
00189 {
00190    m_pathsGUI = new FWPathsPopup(this, guiManager());
00191 
00192    ar.watchPostProcessEvent(m_pathsGUI, &FWPathsPopup::postProcessEvent);
00193    ar.watchPostModule(m_pathsGUI, &FWPathsPopup::postModule);
00194    ar.watchPreModule(m_pathsGUI, &FWPathsPopup::preModule);
00195    ar.watchPostEndJob(this, &FWFFLooper::postEndJob);
00196 }
00197 
00198 FWFFLooper::~FWFFLooper()
00199 {
00200    delete m_MagField;
00201 }
00202 
00203 
00204 //==============================================================================
00205 // Service watchers
00206 //==============================================================================
00207 
00208 void
00209 FWFFLooper::startingNewLoop(unsigned int count)
00210 {
00211    // Initialise on first loop.
00212    if (count == 0)
00213    {
00214       const edm::ScheduleInfo *info = scheduleInfo();
00215       m_pathsGUI->setup(info);
00216 
00217       // We need to enter the GUI loop in order to 
00218       // have all the callbacks executed. The last callback will
00219       // be responsible for returning the control to CMSSW. 
00220       assert(m_Rint);
00221       CmsShowTaskExecutor::TaskFunctor f;
00222       f=boost::bind(&TApplication::Terminate, m_Rint, 0);
00223       startupTasks()->addTask(f);
00224       // FIXME: do we really need to delay tasks like this?
00225       startupTasks()->startDoingTasks(); 
00226       m_Rint->Run(kTRUE);
00227       // Show the GUI ...
00228       gSystem->ProcessEvents();
00229    }
00230 }
00231 
00232 void 
00233 FWFFLooper::postEndJob()
00234 {
00235 //   printf("FWFFLooper::postEndJob\n");
00236 //   TEveManager::Terminate();
00237 }
00238 
00239 void
00240 FWFFLooper::checkPosition()
00241 {
00242    if (loop() && isPlaying())
00243       return;
00244   
00245    guiManager()->getMainFrame()->enableNavigatorControls();
00246    guiManager()->getMainFrame()->enableComplexNavigation(false);
00247 
00248    if (m_isFirstEvent)
00249       guiManager()->disablePrevious();
00250 
00251    if (m_isLastEvent)
00252    {
00253       guiManager()->disableNext();
00254       // force enable play events action in --port mode
00255       if (!guiManager()->playEventsAction()->isEnabled())
00256          guiManager()->playEventsAction()->enable();
00257    }
00258 }
00259 
00264 void
00265 FWFFLooper::autoLoadNewEvent()
00266 {
00267    stopAutoLoadTimer();
00268    bool reachedEnd = (forward() && m_isLastEvent) || (!forward() && m_isFirstEvent);
00269 
00270    if (!reachedEnd || loop())
00271    {
00272       // Will exit the loop here!
00273       m_autoReload = true;
00274       forward() ? m_navigator->nextEvent() : m_navigator->previousEvent();
00275    }
00276    else
00277    {
00278       m_autoReload = false;
00279       setIsPlaying(false);
00280       guiManager()->enableActions();
00281       guiManager()->getMainFrame()->enableComplexNavigation(false);
00282    }
00283 }
00284 
00285 void
00286 FWFFLooper::stopPlaying()
00287 {
00288    stopAutoLoadTimer();
00289    m_autoReload = false;
00290    setIsPlaying(false);
00291    guiManager()->enableActions();
00292    guiManager()->getMainFrame()->enableComplexNavigation(false);
00293    checkPosition();
00294 }
00295 
00296 
00297 //------------------------------------------------------------------------------
00298 
00299 void
00300 FWFFLooper::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup)
00301 {
00302    // Check DisplayGeomRecord changes.
00303    try {
00304       m_geomWatcher.check(iSetup);
00305    }
00306    catch (...) {}
00307    
00308    // If the geometry was not picked up from a file, we try to get it from the
00309    // EventSetup!
00310    // FIXME: we need to check we execute only once because the view managers
00311    //        depend on geometry and they cannot be initialised more than once.
00312    //        This should actually be cleaned up so that the various view manager
00313    //        don't care about geometry.
00314    // FIXME: we should actually be able to update the geometry when requested.
00315    //        this is not possible at the moment.
00316    if (m_firstTime == true)
00317    {
00318       if (m_context->getGeom() == 0)
00319       {
00320          try
00321          {
00322             guiManager()->updateStatus("Loading geometry...");
00323             edm::ESHandle<FWRecoGeometry> geoh;
00324             iSetup.get<FWRecoGeometryRecord>().get(geoh);
00325             getGeom().initMap(geoh.product()->idToName);
00326             m_context->setGeom(&(getGeom()));
00327          }
00328          catch( const cms::Exception& exception )
00329          {
00330             setGeometryFilename("cmsGeom10.root");
00331             CmsShowMainBase::loadGeometry();
00332          }
00333       }
00334 
00335       setupViewManagers();
00336       setupConfiguration();
00337       setupActions();
00338       
00339       guiManager()->showEventFilterGUI_.connect(boost::bind(&FWFFLooper::showPathsGUI, this, _1));
00340       guiManager()->setFilterButtonText("Show paths / CMSSW configuration editor");
00341       guiManager()->filterButtonClicked_.connect(boost::bind(&FWGUIManager::showEventFilterGUI, guiManager()));
00342 
00343       m_firstTime = false;
00344       m_autoReload = false;
00345    }
00346 
00347    float current = 18160.0f;
00348    try {
00349       edm::Handle<edm::ConditionsInRunBlock> runCond;
00350       // bool res = iRun.getByType(runCond);
00351       bool res = iRun.getByLabel("conditionsInEdm", runCond);
00352       if (res && runCond.isValid())
00353       {
00354          printf("Got current from conds in edm %f\n", runCond->BAvgCurrent);
00355          current = runCond->BAvgCurrent;
00356       }
00357       else
00358       {
00359          printf("Could not extract run-conditions get-result=%d, is-valid=%d\n", res, runCond.isValid());
00360 
00361          const edm::eventsetup::EventSetupRecord* rec = iSetup.find( edm::eventsetup::EventSetupRecordKey::makeKey<RunInfoRcd>());
00362          if( 0 != rec )
00363          {
00364             edm::ESHandle<RunInfo> sum;
00365             iSetup.get<RunInfoRcd>().get(sum);
00366 
00367             current = sum->m_avg_current;
00368             printf("Got current from RunInfoRcd %f\n", sum->m_avg_current);
00369          }
00370       }
00371    }
00372    catch (...) {
00373       fwLog(fwlog::kInfo) << "ConditionsInRunBlock not available\n";
00374    }
00375    static_cast<CmsEveMagField*>(m_MagField)->SetFieldByCurrent(current);
00376 }
00377 
00378 //------------------------------------------------------------------------------
00379 edm::EDLooperBase::Status
00380 FWFFLooper::duringLoop(const edm::Event &event, 
00381                        const edm::EventSetup&es, 
00382                        edm::ProcessingController &controller)
00383 {
00384    // Check DisplayGeomRecord changes.
00385    try { 
00386       m_geomWatcher.check(es);
00387    } catch (...) {}
00388    
00389 
00390    m_isLastEvent = controller.forwardState() == edm::ProcessingController::kAtLastEvent;
00391    m_isFirstEvent = controller.reverseState() == edm::ProcessingController::kAtFirstEvent;
00392    // If the next event id is valid, set the transition so 
00393    // that we go to it go to to it.
00394    if (m_nextEventId != edm::EventID())
00395    {
00396       controller.setTransitionToEvent(m_nextEventId);
00397       m_nextEventId = edm::EventID();
00398       return kContinue;
00399    }
00400    // We handle "last event" by going to the first event and then moving to the
00401    // previous event.
00402    if (m_navigator->currentTransition() == FWFFNavigator::kLastEvent)
00403    {
00404       m_navigator->resetTransition();
00405       controller.setTransitionToPreviousEvent();
00406       return kContinue;
00407    }
00408 
00409    m_pathsGUI->hasChanges() = false;
00410    m_metadataManager->update(new FWFFMetadataUpdateRequest(event));
00411    m_navigator->setCurrentEvent(&event);
00412    if (m_autoReload == true)
00413       startAutoLoadTimer();
00414 
00415    checkPosition();
00416    draw();
00417       
00418    m_Rint->Run(kTRUE);
00419    // If the GUI changed the PSet, save the current event to reload
00420    // it on next iteration.
00421    if (m_pathsGUI->hasChanges())
00422    {
00423       m_nextEventId = edm::EventID();
00424       return kStop;
00425    }
00426    else if (m_navigator->currentTransition() == FWFFNavigator::kFirstEvent)
00427    {
00428       m_nextEventId = m_navigator->getFirstEventID();
00429       return kStop;
00430    }
00431    else if (m_navigator->currentTransition() == FWFFNavigator::kLastEvent)
00432    {
00433       m_nextEventId = m_navigator->getFirstEventID();
00434       return kStop;
00435    }
00436    else if (m_navigator->currentTransition() == FWFFNavigator::kNextEvent)
00437       controller.setTransitionToNextEvent();
00438    else if (m_navigator->currentTransition() == FWFFNavigator::kPreviousEvent)
00439       controller.setTransitionToPreviousEvent();
00440    return kContinue;
00441 }
00442 
00443 //------------------------------------------------------------------------------
00444 void 
00445 FWFFLooper::display(const std::string& info)
00446 {
00447    // Display whatever was registered so far, wait until user presses
00448    // the "Step" button.
00449 
00450    if (m_AllowStep)
00451    {
00452       gEve->Redraw3D();
00453       m_Rint->Run(kTRUE);
00454    }
00455 }
00456 
00457 //==============================================================================
00458 // Getters for cleints
00459 //==============================================================================
00460 
00461 TEveMagField* 
00462 FWFFLooper::getMagField()
00463 {
00464    return m_MagField;
00465 }
00466 
00467 void 
00468 FWFFLooper::setupFieldForPropagator(TEveTrackPropagator* prop)
00469 {
00470    prop->SetMagFieldObj(m_MagField, kFALSE);
00471 }
00472 
00473 void 
00474 FWFFLooper::quit()
00475 {
00476    gSystem->ExitLoop();
00477 
00478    // Throwing exception here is bad because:
00479    //   a) it does not work when in a "debug step";
00480    //   b) does not restore terminal state.
00481    // So we do exit instead for now.
00482    // throw cms::Exception("UserTerminationRequest");
00483    gSystem->Exit(0);
00484 }
00485 
00490 edm::EDLooperBase::Status
00491 FWFFLooper::endOfLoop(const edm::EventSetup&, unsigned int)
00492 {
00493    // Looks like the module changer is availble only here.
00494    for (ModuleChanges::iterator i = m_scheduledChanges.begin(),
00495                                 e = m_scheduledChanges.end();
00496         i != e; ++i)
00497    {
00498       try {
00499          moduleChanger()->changeModule(i->first, i->second);
00500       }
00501       catch (cms::Exception const& e)
00502       { 
00503          fwLog(fwlog::kError) << "FWFFLooper::endOfLoop caught exception.\n";
00504          std::cerr << e.what() << std::endl;
00505       } 
00506    }
00507    m_scheduledChanges.clear();
00508    return kContinue;
00509 }
00510 
00511 void
00512 FWFFLooper::showPathsGUI(const TGWindow *)
00513 {
00514    if (!m_pathsGUI)
00515       return;
00516    if (m_pathsGUI->IsMapped())
00517    {
00518       guiManager()->setFilterButtonText("Show paths / CMSSW configuration editor");
00519       m_pathsGUI->UnmapWindow();
00520    }
00521    else
00522    {
00523       guiManager()->setFilterButtonText("Hide paths / CMSSW configuration editor");
00524       m_pathsGUI->MapWindow();
00525    }
00526 }
00527 
00528 void
00529 FWFFLooper::requestChanges(const std::string &moduleLabel, const edm::ParameterSet& ps)
00530 {
00531    m_scheduledChanges[moduleLabel] = ps;
00532 }
00533  
00534 
00535 //______________________________________________________________________________
00536 // AMT : I'm not sure if geometry can change in the two functionss. Plese delete
00537 // them if you think this is impossible
00538 
00539 void FWFFLooper::doBeginLuminosityBlock(edm::LuminosityBlockPrincipal& iLB, edm::EventSetup const& iES)
00540 {
00541    try {
00542       m_geomWatcher.check(iES);
00543    } catch (...) {}
00544    
00545    EDLooperBase::doBeginLuminosityBlock(iLB, iES);
00546 }
00547 
00548 void FWFFLooper::doEndLuminosityBlock(edm::LuminosityBlockPrincipal& iLB, edm::EventSetup const& iES)
00549 {
00550    try {
00551       m_geomWatcher.check(iES);
00552    }  catch (...) {}
00553    
00554    EDLooperBase::doEndLuminosityBlock(iLB, iES);
00555 }
00556 
00557 //______________________________________________________________________________
00558 
00559 void
00560 FWFFLooper::remakeGeometry(const DisplayGeomRecord& dgRec)
00561 {
00562    fwLog(fwlog::kInfo) << "FWFFLooper set TGeo geomtery from DisplayGeomRecord.\n";
00563 
00564    edm::ESHandle<TGeoManager> geom;
00565    dgRec.get(geom);
00566    TEveGeoManagerHolder _tgeo(const_cast<TGeoManager*>(geom.product()));
00567    FWGeometryTableViewManager::setGeoManagerRuntime(gGeoManager);
00568 }