Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:45

0001 #include <functional>
0002 #include <iostream>
0003 
0004 #include "Fireworks/FWInterface/interface/FWFFLooper.h"
0005 #include "Fireworks/FWInterface/src/FWFFNavigator.h"
0006 #include "Fireworks/FWInterface/src/FWFFMetadataManager.h"
0007 #include "Fireworks/FWInterface/src/FWFFMetadataUpdateRequest.h"
0008 #include "Fireworks/FWInterface/src/FWPathsPopup.h"
0009 #include "Fireworks/Core/interface/FWConfigurationManager.h"
0010 #include "Fireworks/Core/interface/Context.h"
0011 #include "Fireworks/Core/interface/FWEventItemsManager.h"
0012 #include "Fireworks/Core/interface/CmsShowTaskExecutor.h"
0013 #include "Fireworks/Core/interface/CmsShowMainFrame.h"
0014 #include "Fireworks/Core/interface/FWGUIManager.h"
0015 #include "Fireworks/Core/interface/CSGContinuousAction.h"
0016 #include "Fireworks/Core/interface/FWRecoGeom.h"
0017 #include "Fireworks/Core/interface/FWGeometryTableViewManager.h"
0018 #include "Fireworks/Core/interface/fwLog.h"
0019 #include "Fireworks/Core/interface/FWMagField.h"
0020 #include "Fireworks/Geometry/interface/FWRecoGeometry.h"
0021 #include "Fireworks/Geometry/interface/FWRecoGeometryRecord.h"
0022 
0023 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0024 #include "FWCore/ServiceRegistry/interface/ActivityRegistry.h"
0025 
0026 #include "FWCore/Framework/interface/EventSetup.h"
0027 #include "FWCore/Framework/interface/ESHandle.h"
0028 #include "FWCore/Framework/interface/ESWatcher.h"
0029 #include "FWCore/Framework/interface/ProcessingController.h"
0030 #include "FWCore/Framework/interface/ScheduleInfo.h"
0031 #include "FWCore/Framework/interface/ModuleChanger.h"
0032 #include "CondFormats/RunInfo/interface/RunInfo.h"
0033 #include "FWCore/Framework/interface/ESTransientHandle.h"
0034 #include "CondFormats/DataRecord/interface/RunSummaryRcd.h"
0035 #include "FWCore/Framework/interface/Run.h"
0036 #include "DataFormats/Common/interface/Handle.h"
0037 #include "DataFormats/Common/interface/ConditionsInEdm.h"
0038 #include "DataFormats/FWLite/interface/LuminosityBlock.h"
0039 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0040 
0041 #include "TROOT.h"
0042 #include "TSystem.h"
0043 #include "TRint.h"
0044 #include "TGLWidget.h"
0045 
0046 #include "TEveManager.h"
0047 #include "TEveEventManager.h"
0048 #include "TEveTrackPropagator.h"
0049 #include "TEveBrowser.h"
0050 #include "TGeoManager.h"
0051 
0052 namespace edm {
0053   class StreamContext;
0054   class ModuleCallingContext;
0055 }  // namespace edm
0056 
0057 namespace {
0058   class CmsEveMagField : public TEveMagField {
0059   private:
0060     Float_t fField;
0061     Float_t fFieldMag;
0062 
0063   public:
0064     CmsEveMagField() : TEveMagField(), fField(-3.8), fFieldMag(3.8) {}
0065     ~CmsEveMagField() override {}
0066 
0067     // set current
0068     void SetFieldByCurrent(Float_t avg_current) {
0069       fField = -3.8 * avg_current / 18160.0;
0070       fFieldMag = TMath::Abs(fField);
0071     }
0072 
0073     // get field values
0074     Float_t GetMaxFieldMag() const override { return fFieldMag; }
0075 
0076     TEveVector GetField(Float_t x, Float_t y, Float_t z) const override {
0077       static const Float_t barrelFac = 1.2 / 3.8;
0078       static const Float_t endcapFac = 2.0 / 3.8;
0079 
0080       const Float_t R = sqrt(x * x + y * y);
0081       const Float_t absZ = TMath::Abs(z);
0082 
0083       //barrel
0084       if (absZ < 724.0f) {
0085         //inside solenoid
0086         if (R < 300.0f)
0087           return TEveVector(0, 0, fField);
0088 
0089         // outside solinoid
0090         if ((R > 461.0f && R < 490.5f) || (R > 534.5f && R < 597.5f) || (R > 637.0f && R < 700.0f)) {
0091           return TEveVector(0, 0, -fField * barrelFac);
0092         }
0093       } else {
0094         if ((absZ > 724.0f && absZ < 786.0f) || (absZ > 850.0f && absZ < 910.0f) || (absZ > 975.0f && absZ < 1003.0f)) {
0095           const Float_t fac = (z >= 0 ? fField : -fField) * endcapFac / R;
0096           return TEveVector(x * fac, y * fac, 0);
0097         }
0098       }
0099       return TEveVector(0, 0, 0);
0100     }
0101   };
0102 }  // namespace
0103 
0104 //
0105 // constants, enums and typedefs
0106 //
0107 
0108 //
0109 // static data member definitions
0110 //
0111 
0112 //==============================================================================
0113 // constructors and destructor
0114 //==============================================================================
0115 
0116 FWFFLooper::FWFFLooper(edm::ParameterSet const& ps)
0117     : CmsShowMainBase(),
0118       m_navigator(new FWFFNavigator(*this)),
0119       m_metadataManager(new FWFFMetadataManager()),
0120       m_context(new fireworks::Context(
0121           changeManager(), selectionManager(), eiManager(), colorManager(), m_metadataManager.get())),
0122       m_Rint(m_appHelper->app()),
0123       m_AllowStep(true),
0124       m_ShowEvent(true),
0125       m_firstTime(true),
0126       m_pathsGUI(nullptr),
0127       m_geomWatcher(this, &FWFFLooper::remakeGeometry),
0128       m_recoGeomToken(esConsumes()),
0129       m_runInfoToken(esConsumes()),
0130       m_displayGeomToken(esConsumes()) {
0131   setup(m_navigator.get(), m_context.get(), m_metadataManager.get());
0132 
0133   eiManager()->setContext(m_context.get());
0134 
0135   // By default, we look up geometry and configuration in the workarea, then
0136   // in the release area then in the local directory.  It is also possible to
0137   // override those locations by using the displayConfigurationFilename and
0138   // geometryFilename in the parameterset.
0139   const char* releaseBase = std::getenv("CMSSW_RELEASE_BASE");
0140   const char* workarea = std::getenv("CMSSW_BASE");
0141   std::string displayConfigRelFilename = "/src/Fireworks/FWInterface/macros/ffw.fwc";
0142   std::string geometryRelFilename = "/src/Fireworks/FWInterface/data/cmsGeom10.root";
0143 
0144   std::string displayConfigFilename = "ffw.fwc";
0145   std::string geometryFilename;
0146 
0147   if (releaseBase && access((releaseBase + displayConfigFilename).c_str(), R_OK) == 0)
0148     displayConfigFilename = releaseBase + displayConfigRelFilename;
0149   if (workarea && access((workarea + displayConfigRelFilename).c_str(), R_OK) == 0)
0150     displayConfigFilename = workarea + displayConfigRelFilename;
0151 
0152   if (releaseBase && access((releaseBase + geometryRelFilename).c_str(), R_OK) == 0)
0153     geometryFilename = releaseBase + geometryRelFilename;
0154   if (workarea && access((workarea + geometryRelFilename).c_str(), R_OK) == 0)
0155     geometryFilename = workarea + geometryRelFilename;
0156 
0157   displayConfigFilename = ps.getUntrackedParameter<std::string>("displayConfigFilename", displayConfigFilename);
0158   geometryFilename = ps.getUntrackedParameter<std::string>("geometryFilename", geometryFilename);
0159   if (!geometryFilename.empty()) {
0160     loadDefaultGeometryFile();
0161   }
0162   setGeometryFilename(geometryFilename);
0163   setConfigFilename(displayConfigFilename);
0164 
0165   if (!geometryFilename.empty()) {
0166     loadDefaultGeometryFile();
0167   }
0168 
0169   m_MagField = new CmsEveMagField();
0170 }
0171 
0172 void FWFFLooper::loadDefaultGeometryFile(void) {
0173   CmsShowTaskExecutor::TaskFunctor f;
0174   f = std::bind(&CmsShowMainBase::loadGeometry, this);
0175   startupTasks()->addTask(f);
0176 }
0177 
0178 void FWFFLooper::attachTo(edm::ActivityRegistry& ar) {
0179   m_pathsGUI = new FWPathsPopup(this, guiManager());
0180 
0181   ar.watchPostModuleEvent(m_pathsGUI, &FWPathsPopup::postModuleEvent);
0182   ar.watchPreModuleEvent(m_pathsGUI, &FWPathsPopup::preModuleEvent);
0183   ar.watchPostEndJob(this, &FWFFLooper::postEndJob);
0184 }
0185 
0186 FWFFLooper::~FWFFLooper() { delete m_MagField; }
0187 
0188 //==============================================================================
0189 // Service watchers
0190 //==============================================================================
0191 
0192 void FWFFLooper::startingNewLoop(unsigned int count) {
0193   // Initialise on first loop.
0194   if (count == 0) {
0195     const edm::ScheduleInfo* info = scheduleInfo();
0196     m_pathsGUI->setup(info);
0197 
0198     // We need to enter the GUI loop in order to
0199     // have all the callbacks executed. The last callback will
0200     // be responsible for returning the control to CMSSW.
0201     assert(m_Rint);
0202     CmsShowTaskExecutor::TaskFunctor f;
0203     f = std::bind(&TApplication::Terminate, m_Rint, 0);
0204     startupTasks()->addTask(f);
0205     // FIXME: do we really need to delay tasks like this?
0206     startupTasks()->startDoingTasks();
0207     m_Rint->Run(kTRUE);
0208     // Show the GUI ...
0209     gSystem->ProcessEvents();
0210   }
0211 }
0212 
0213 void FWFFLooper::postEndJob() {
0214   printf("FWFFLooper::postEndJob\n");
0215   TEveManager::Terminate();
0216 }
0217 
0218 void FWFFLooper::checkPosition() {
0219   if (loop() && isPlaying())
0220     return;
0221 
0222   guiManager()->getMainFrame()->enableNavigatorControls();
0223   guiManager()->getMainFrame()->enableComplexNavigation(false);
0224 
0225   if (m_isFirstEvent)
0226     guiManager()->disablePrevious();
0227 
0228   if (m_isLastEvent) {
0229     guiManager()->disableNext();
0230     // force enable play events action in --port mode
0231     if (!guiManager()->playEventsAction()->isEnabled())
0232       guiManager()->playEventsAction()->enable();
0233   }
0234 }
0235 
0236 /** This actually needs to be different from the standalone
0237     case because nextEvent() / previousEvent() will immediately
0238     interrupt the GUI event loop and fall back to the looper.
0239   */
0240 void FWFFLooper::autoLoadNewEvent() {
0241   stopAutoLoadTimer();
0242   bool reachedEnd = (forward() && m_isLastEvent) || (!forward() && m_isFirstEvent);
0243 
0244   if (!reachedEnd || loop()) {
0245     // Will exit the loop here!
0246     m_autoReload = true;
0247     forward() ? m_navigator->nextEvent() : m_navigator->previousEvent();
0248   } else {
0249     m_autoReload = false;
0250     CmsShowMainBase::stopPlaying();
0251     guiManager()->enableActions();
0252     guiManager()->getMainFrame()->enableComplexNavigation(false);
0253   }
0254 }
0255 
0256 void FWFFLooper::stopPlaying() {
0257   stopAutoLoadTimer();
0258   m_autoReload = false;
0259   CmsShowMainBase::stopPlaying();
0260   guiManager()->enableActions();
0261   guiManager()->getMainFrame()->enableComplexNavigation(false);
0262   checkPosition();
0263 }
0264 
0265 //------------------------------------------------------------------------------
0266 
0267 void FWFFLooper::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
0268   // Check DisplayGeomRecord changes.
0269   try {
0270     m_geomWatcher.check(iSetup);
0271   } catch (...) {
0272   }
0273 
0274   // If the geometry was not picked up from a file, we try to get it from the
0275   // EventSetup!
0276   // FIXME: we need to check we execute only once because the view managers
0277   //        depend on geometry and they cannot be initialised more than once.
0278   //        This should actually be cleaned up so that the various view manager
0279   //        don't care about geometry.
0280   // FIXME: we should actually be able to update the geometry when requested.
0281   //        this is not possible at the moment.
0282   if (m_firstTime == true) {
0283     if (m_context->getGeom() == nullptr) {
0284       try {
0285         guiManager()->updateStatus("Loading geometry...");
0286         getGeom().initMap(iSetup.getData(m_recoGeomToken).idToName);
0287         m_context->setGeom(&(getGeom()));
0288       } catch (const cms::Exception& exception) {
0289         setGeometryFilename("cmsGeom10.root");
0290         CmsShowMainBase::loadGeometry();
0291       }
0292     }
0293 
0294     setupViewManagers();
0295     setupConfiguration();
0296     setupActions();
0297 
0298     guiManager()->showEventFilterGUI_.connect(std::bind(&FWFFLooper::showPathsGUI, this, std::placeholders::_1));
0299     guiManager()->setFilterButtonText("Show paths / CMSSW configuration editor");
0300     guiManager()->filterButtonClicked_.connect(std::bind(&FWGUIManager::showEventFilterGUI, guiManager()));
0301 
0302     m_firstTime = false;
0303     m_autoReload = false;
0304   }
0305 
0306   float current = 18160.0f;
0307   try {
0308     edm::Handle<edm::ConditionsInRunBlock> runCond;
0309     // bool res = iRun.getByType(runCond);
0310     bool res = iRun.getByLabel("conditionsInEdm", runCond);
0311     if (res && runCond.isValid()) {
0312       printf("Got current from conds in edm %f\n", runCond->BAvgCurrent);
0313       current = runCond->BAvgCurrent;
0314     } else {
0315       printf("Could not extract run-conditions get-result=%d, is-valid=%d\n", res, runCond.isValid());
0316 
0317       auto rec = iSetup.find(edm::eventsetup::EventSetupRecordKey::makeKey<RunInfoRcd>());
0318       if (rec) {
0319         RunInfo const& sum = iSetup.getData(m_runInfoToken);
0320 
0321         current = sum.m_avg_current;
0322         printf("Got current from RunInfoRcd %f\n", sum.m_avg_current);
0323       }
0324     }
0325   } catch (...) {
0326     fwLog(fwlog::kInfo) << "ConditionsInRunBlock not available\n";
0327   }
0328   static_cast<CmsEveMagField*>(m_MagField)->SetFieldByCurrent(current);
0329   context()->getField()->setFFFieldMag(m_MagField->GetMaxFieldMag());
0330 }
0331 
0332 //------------------------------------------------------------------------------
0333 edm::EDLooperBase::Status FWFFLooper::duringLoop(const edm::Event& event,
0334                                                  const edm::EventSetup& es,
0335                                                  edm::ProcessingController& controller) {
0336   // Check DisplayGeomRecord changes.
0337   try {
0338     m_geomWatcher.check(es);
0339   } catch (...) {
0340   }
0341 
0342   m_pathsGUI->postEvent(event);
0343 
0344   m_isLastEvent = controller.forwardState() == edm::ProcessingController::kAtLastEvent;
0345   m_isFirstEvent = controller.reverseState() == edm::ProcessingController::kAtFirstEvent;
0346   // If the next event id is valid, set the transition so
0347   // that we go to it go to to it.
0348   if (m_nextEventId != edm::EventID()) {
0349     controller.setTransitionToEvent(m_nextEventId);
0350     m_nextEventId = edm::EventID();
0351     return kContinue;
0352   }
0353   // We handle "last event" by going to the first event and then moving to the
0354   // previous event.
0355   if (m_navigator->currentTransition() == FWFFNavigator::kLastEvent) {
0356     m_navigator->resetTransition();
0357     controller.setTransitionToPreviousEvent();
0358     return kContinue;
0359   }
0360 
0361   m_pathsGUI->hasChanges() = false;
0362   m_metadataManager->update(new FWFFMetadataUpdateRequest(event));
0363   m_navigator->setCurrentEvent(&event);
0364   if (m_autoReload == true)
0365     startAutoLoadTimer();
0366 
0367   checkPosition();
0368   draw();
0369 
0370   m_Rint->Run(kTRUE);
0371   // If the GUI changed the PSet, save the current event to reload
0372   // it on next iteration.
0373   if (m_pathsGUI->hasChanges()) {
0374     m_nextEventId = edm::EventID();
0375     return kStop;
0376   } else if (m_navigator->currentTransition() == FWFFNavigator::kFirstEvent) {
0377     m_nextEventId = m_navigator->getFirstEventID();
0378     return kStop;
0379   } else if (m_navigator->currentTransition() == FWFFNavigator::kLastEvent) {
0380     m_nextEventId = m_navigator->getFirstEventID();
0381     return kStop;
0382   } else if (m_navigator->currentTransition() == FWFFNavigator::kNextEvent)
0383     controller.setTransitionToNextEvent();
0384   else if (m_navigator->currentTransition() == FWFFNavigator::kPreviousEvent)
0385     controller.setTransitionToPreviousEvent();
0386   return kContinue;
0387 }
0388 
0389 //------------------------------------------------------------------------------
0390 void FWFFLooper::display(const std::string& info) {
0391   // Display whatever was registered so far, wait until user presses
0392   // the "Step" button.
0393 
0394   if (m_AllowStep) {
0395     gEve->Redraw3D();
0396     m_Rint->Run(kTRUE);
0397   }
0398 }
0399 
0400 //==============================================================================
0401 // Getters for cleints
0402 //==============================================================================
0403 
0404 TEveMagField* FWFFLooper::getMagField() { return m_MagField; }
0405 
0406 void FWFFLooper::setupFieldForPropagator(TEveTrackPropagator* prop) { prop->SetMagFieldObj(m_MagField, kFALSE); }
0407 
0408 void FWFFLooper::quit() {
0409   gSystem->ExitLoop();
0410 
0411   // Throwing exception here is bad because:
0412   //   a) it does not work when in a "debug step";
0413   //   b) does not restore terminal state.
0414   // So we do exit instead for now.
0415   // throw cms::Exception("UserTerminationRequest");
0416   gSystem->Exit(0);
0417 }
0418 
0419 /** This is called at the end of looping.
0420     We always continue because we want the transition
0421     set in the ProcessingController to happen.
0422   */
0423 edm::EDLooperBase::Status FWFFLooper::endOfLoop(const edm::EventSetup&, unsigned int) {
0424   // Looks like the module changer is availble only here.
0425   for (ModuleChanges::iterator i = m_scheduledChanges.begin(), e = m_scheduledChanges.end(); i != e; ++i) {
0426     try {
0427       moduleChanger()->changeModule(i->first, i->second);
0428     } catch (cms::Exception const& e) {
0429       fwLog(fwlog::kError) << "FWFFLooper::endOfLoop caught exception.\n";
0430       std::cerr << e.what() << std::endl;
0431     }
0432   }
0433   m_scheduledChanges.clear();
0434   return kContinue;
0435 }
0436 
0437 void FWFFLooper::showPathsGUI(const TGWindow*) {
0438   if (!m_pathsGUI)
0439     return;
0440   if (m_pathsGUI->IsMapped()) {
0441     guiManager()->setFilterButtonText("Show paths / CMSSW configuration editor");
0442     m_pathsGUI->UnmapWindow();
0443   } else {
0444     guiManager()->setFilterButtonText("Hide paths / CMSSW configuration editor");
0445     m_pathsGUI->MapWindow();
0446   }
0447 }
0448 
0449 void FWFFLooper::requestChanges(const std::string& moduleLabel, const edm::ParameterSet& ps) {
0450   m_scheduledChanges[moduleLabel] = ps;
0451 }
0452 
0453 //______________________________________________________________________________
0454 
0455 void FWFFLooper::remakeGeometry(const DisplayGeomRecord& dgRec) {
0456   fwLog(fwlog::kInfo) << "FWFFLooper set TGeo geometry from DisplayGeomRecord.\n";
0457 
0458   TEveGeoManagerHolder _tgeo(const_cast<TGeoManager*>(&dgRec.get(m_displayGeomToken)));
0459   FWGeometryTableViewManager::setGeoManagerRuntime(gGeoManager);
0460 }