CMS 3D CMS Logo

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