CMS 3D CMS Logo

FWFFLooper.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include "boost/bind.hpp"
3 
22 
25 
40 
41 #include "TROOT.h"
42 #include "TSystem.h"
43 #include "TRint.h"
44 #include "TGLWidget.h"
45 
46 #include "TEveManager.h"
47 #include "TEveEventManager.h"
48 #include "TEveTrackPropagator.h"
49 #include "TEveBrowser.h"
50 #include "TGeoManager.h"
51 
52 
53 namespace edm
54 {
55  class StreamContext;
56  class ModuleCallingContext;
57 }
58 
59 namespace
60 {
61  class CmsEveMagField : public TEveMagField
62  {
63  private:
64  Float_t fField;
65  Float_t fFieldMag;
66 
67  public:
68 
69  CmsEveMagField() : TEveMagField(), fField(-3.8), fFieldMag(3.8) {}
70  ~CmsEveMagField() override {}
71 
72  // set current
73  void SetFieldByCurrent(Float_t avg_current)
74  {
75  fField = -3.8 * avg_current / 18160.0;
76  fFieldMag = TMath::Abs(fField);
77  }
78 
79  // get field values
80  Float_t GetMaxFieldMag() const override
81  {
82  return fFieldMag;
83  }
84 
85  TEveVector GetField(Float_t x, Float_t y, Float_t z) const override
86  {
87  static const Float_t barrelFac = 1.2 / 3.8;
88  static const Float_t endcapFac = 2.0 / 3.8;
89 
90  const Float_t R = sqrt(x*x+y*y);
91  const Float_t absZ = TMath::Abs(z);
92 
93  //barrel
94  if (absZ < 724.0f)
95  {
96  //inside solenoid
97  if (R < 300.0f) return TEveVector(0, 0, fField);
98 
99  // outside solinoid
100  if ((R > 461.0f && R < 490.5f) ||
101  (R > 534.5f && R < 597.5f) ||
102  (R > 637.0f && R < 700.0f))
103  {
104  return TEveVector(0, 0, -fField*barrelFac);
105  }
106  } else {
107  if ((absZ > 724.0f && absZ < 786.0f) ||
108  (absZ > 850.0f && absZ < 910.0f) ||
109  (absZ > 975.0f && absZ < 1003.0f))
110  {
111  const Float_t fac = (z >= 0 ? fField : -fField) * endcapFac / R;
112  return TEveVector(x*fac, y*fac, 0);
113  }
114  }
115  return TEveVector(0, 0, 0);
116  }
117  };
118 }
119 
120 //
121 // constants, enums and typedefs
122 //
123 
124 //
125 // static data member definitions
126 //
127 
128 //==============================================================================
129 // constructors and destructor
130 //==============================================================================
131 
133  : CmsShowMainBase(),
134  m_navigator(new FWFFNavigator(*this)),
135  m_metadataManager(new FWFFMetadataManager()),
136  m_context(new fireworks::Context(changeManager(),
137  selectionManager(),
138  eiManager(),
139  colorManager(),
140  m_metadataManager.get())),
141  m_Rint(m_appHelper->app()),
142  m_AllowStep(true),
143  m_ShowEvent(true),
144  m_firstTime(true),
145  m_pathsGUI(nullptr),
146  m_geomWatcher(this, &FWFFLooper::remakeGeometry)
147 {
148  setup(m_navigator.get(), m_context.get(), m_metadataManager.get());
149 
150  eiManager()->setContext(m_context.get());
151 
152  // By default, we look up geometry and configuration in the workarea, then
153  // in the release area then in the local directory. It is also possible to
154  // override those locations by using the displayConfigurationFilename and
155  // geometryFilename in the parameterset.
156  const char *releaseBase = getenv("CMSSW_RELEASE_BASE");
157  const char *workarea = getenv("CMSSW_BASE");
158  std::string displayConfigRelFilename = "/src/Fireworks/FWInterface/macros/ffw.fwc";
159  std::string geometryRelFilename = "/src/Fireworks/FWInterface/data/cmsGeom10.root";
160 
161  std::string displayConfigFilename = "ffw.fwc";
162  std::string geometryFilename;
163 
164  if (releaseBase && access((releaseBase + displayConfigFilename).c_str(), R_OK) == 0)
165  displayConfigFilename = releaseBase + displayConfigRelFilename;
166  if (workarea && access((workarea + displayConfigRelFilename).c_str(), R_OK) == 0)
167  displayConfigFilename = workarea + displayConfigRelFilename;
168 
169  if (releaseBase && access((releaseBase + geometryRelFilename).c_str(), R_OK) == 0)
170  geometryFilename = releaseBase + geometryRelFilename;
171  if (workarea && access((workarea + geometryRelFilename).c_str(), R_OK) == 0)
172  geometryFilename = workarea + geometryRelFilename;
173 
174  displayConfigFilename = ps.getUntrackedParameter<std::string>("displayConfigFilename", displayConfigFilename);
175  geometryFilename = ps.getUntrackedParameter<std::string>("geometryFilename", geometryFilename);
176  if( !geometryFilename.empty())
177  {
178  loadDefaultGeometryFile();
179  }
180  setGeometryFilename(geometryFilename);
181  setConfigFilename(displayConfigFilename);
182 
183  if( !geometryFilename.empty())
184  {
185  loadDefaultGeometryFile();
186  }
187 
188  m_MagField = new CmsEveMagField();
189 }
190 
191 void
193 {
195  f=boost::bind( &CmsShowMainBase::loadGeometry, this );
196  startupTasks()->addTask( f );
197 }
198 
199 void
201 {
202  m_pathsGUI = new FWPathsPopup(this, guiManager());
203 
207 }
208 
210 {
211  delete m_MagField;
212 }
213 
214 
215 //==============================================================================
216 // Service watchers
217 //==============================================================================
218 
219 void
221 {
222  // Initialise on first loop.
223  if (count == 0)
224  {
225  const edm::ScheduleInfo *info = scheduleInfo();
226  m_pathsGUI->setup(info);
227 
228  // We need to enter the GUI loop in order to
229  // have all the callbacks executed. The last callback will
230  // be responsible for returning the control to CMSSW.
231  assert(m_Rint);
233  f=boost::bind(&TApplication::Terminate, m_Rint, 0);
234  startupTasks()->addTask(f);
235  // FIXME: do we really need to delay tasks like this?
236  startupTasks()->startDoingTasks();
237  m_Rint->Run(kTRUE);
238  // Show the GUI ...
239  gSystem->ProcessEvents();
240  }
241 }
242 
243 void
245 {
246  printf("FWFFLooper::postEndJob\n");
247  TEveManager::Terminate();
248 }
249 
250 void
252 {
253  if (loop() && isPlaying())
254  return;
255 
256  guiManager()->getMainFrame()->enableNavigatorControls();
257  guiManager()->getMainFrame()->enableComplexNavigation(false);
258 
259  if (m_isFirstEvent)
260  guiManager()->disablePrevious();
261 
262  if (m_isLastEvent)
263  {
264  guiManager()->disableNext();
265  // force enable play events action in --port mode
266  if (!guiManager()->playEventsAction()->isEnabled())
267  guiManager()->playEventsAction()->enable();
268  }
269 }
270 
275 void
277 {
278  stopAutoLoadTimer();
279  bool reachedEnd = (forward() && m_isLastEvent) || (!forward() && m_isFirstEvent);
280 
281  if (!reachedEnd || loop())
282  {
283  // Will exit the loop here!
284  m_autoReload = true;
285  forward() ? m_navigator->nextEvent() : m_navigator->previousEvent();
286  }
287  else
288  {
289  m_autoReload = false;
291  guiManager()->enableActions();
292  guiManager()->getMainFrame()->enableComplexNavigation(false);
293  }
294 }
295 
296 void
298 {
299  stopAutoLoadTimer();
300  m_autoReload = false;
302  guiManager()->enableActions();
303  guiManager()->getMainFrame()->enableComplexNavigation(false);
304  checkPosition();
305 }
306 
307 
308 //------------------------------------------------------------------------------
309 
310 void
311 FWFFLooper::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup)
312 {
313  // Check DisplayGeomRecord changes.
314  try {
315  m_geomWatcher.check(iSetup);
316  }
317  catch (...) {}
318 
319  // If the geometry was not picked up from a file, we try to get it from the
320  // EventSetup!
321  // FIXME: we need to check we execute only once because the view managers
322  // depend on geometry and they cannot be initialised more than once.
323  // This should actually be cleaned up so that the various view manager
324  // don't care about geometry.
325  // FIXME: we should actually be able to update the geometry when requested.
326  // this is not possible at the moment.
327  if (m_firstTime == true)
328  {
329  if (m_context->getGeom() == nullptr)
330  {
331  try
332  {
333  guiManager()->updateStatus("Loading geometry...");
335  iSetup.get<FWRecoGeometryRecord>().get(geoh);
336  getGeom().initMap(geoh.product()->idToName);
337  m_context->setGeom(&(getGeom()));
338  }
339  catch( const cms::Exception& exception )
340  {
341  setGeometryFilename("cmsGeom10.root");
343  }
344  }
345 
346  setupViewManagers();
347  setupConfiguration();
348  setupActions();
349 
350  guiManager()->showEventFilterGUI_.connect(boost::bind(&FWFFLooper::showPathsGUI, this, _1));
351  guiManager()->setFilterButtonText("Show paths / CMSSW configuration editor");
352  guiManager()->filterButtonClicked_.connect(boost::bind(&FWGUIManager::showEventFilterGUI, guiManager()));
353 
354  m_firstTime = false;
355  m_autoReload = false;
356  }
357 
358  float current = 18160.0f;
359  try {
361  // bool res = iRun.getByType(runCond);
362  bool res = iRun.getByLabel("conditionsInEdm", runCond);
363  if (res && runCond.isValid())
364  {
365  printf("Got current from conds in edm %f\n", runCond->BAvgCurrent);
366  current = runCond->BAvgCurrent;
367  }
368  else
369  {
370  printf("Could not extract run-conditions get-result=%d, is-valid=%d\n", res, runCond.isValid());
371 
372  auto rec = iSetup.find( edm::eventsetup::EventSetupRecordKey::makeKey<RunInfoRcd>());
373  if( rec )
374  {
376  iSetup.get<RunInfoRcd>().get(sum);
377 
378  current = sum->m_avg_current;
379  printf("Got current from RunInfoRcd %f\n", sum->m_avg_current);
380  }
381  }
382  }
383  catch (...) {
384  fwLog(fwlog::kInfo) << "ConditionsInRunBlock not available\n";
385  }
386  static_cast<CmsEveMagField*>(m_MagField)->SetFieldByCurrent(current);
387  context()->getField()->setFFFieldMag(m_MagField->GetMaxFieldMag());
388 }
389 
390 //------------------------------------------------------------------------------
393  const edm::EventSetup&es,
394  edm::ProcessingController &controller)
395 {
396  // Check DisplayGeomRecord changes.
397  try {
398  m_geomWatcher.check(es);
399  } catch (...) {}
400 
401 
402  m_pathsGUI->postEvent(event);
403 
404  m_isLastEvent = controller.forwardState() == edm::ProcessingController::kAtLastEvent;
405  m_isFirstEvent = controller.reverseState() == edm::ProcessingController::kAtFirstEvent;
406  // If the next event id is valid, set the transition so
407  // that we go to it go to to it.
408  if (m_nextEventId != edm::EventID())
409  {
410  controller.setTransitionToEvent(m_nextEventId);
411  m_nextEventId = edm::EventID();
412  return kContinue;
413  }
414  // We handle "last event" by going to the first event and then moving to the
415  // previous event.
416  if (m_navigator->currentTransition() == FWFFNavigator::kLastEvent)
417  {
418  m_navigator->resetTransition();
419  controller.setTransitionToPreviousEvent();
420  return kContinue;
421  }
422 
423  m_pathsGUI->hasChanges() = false;
424  m_metadataManager->update(new FWFFMetadataUpdateRequest(event));
425  m_navigator->setCurrentEvent(&event);
426  if (m_autoReload == true)
427  startAutoLoadTimer();
428 
429  checkPosition();
430  draw();
431 
432  m_Rint->Run(kTRUE);
433  // If the GUI changed the PSet, save the current event to reload
434  // it on next iteration.
435  if (m_pathsGUI->hasChanges())
436  {
437  m_nextEventId = edm::EventID();
438  return kStop;
439  }
440  else if (m_navigator->currentTransition() == FWFFNavigator::kFirstEvent)
441  {
442  m_nextEventId = m_navigator->getFirstEventID();
443  return kStop;
444  }
445  else if (m_navigator->currentTransition() == FWFFNavigator::kLastEvent)
446  {
447  m_nextEventId = m_navigator->getFirstEventID();
448  return kStop;
449  }
450  else if (m_navigator->currentTransition() == FWFFNavigator::kNextEvent)
451  controller.setTransitionToNextEvent();
452  else if (m_navigator->currentTransition() == FWFFNavigator::kPreviousEvent)
453  controller.setTransitionToPreviousEvent();
454  return kContinue;
455 }
456 
457 //------------------------------------------------------------------------------
458 void
460 {
461  // Display whatever was registered so far, wait until user presses
462  // the "Step" button.
463 
464  if (m_AllowStep)
465  {
466  gEve->Redraw3D();
467  m_Rint->Run(kTRUE);
468  }
469 }
470 
471 //==============================================================================
472 // Getters for cleints
473 //==============================================================================
474 
475 TEveMagField*
477 {
478  return m_MagField;
479 }
480 
481 void
482 FWFFLooper::setupFieldForPropagator(TEveTrackPropagator* prop)
483 {
484  prop->SetMagFieldObj(m_MagField, kFALSE);
485 }
486 
487 void
489 {
490  gSystem->ExitLoop();
491 
492  // Throwing exception here is bad because:
493  // a) it does not work when in a "debug step";
494  // b) does not restore terminal state.
495  // So we do exit instead for now.
496  // throw cms::Exception("UserTerminationRequest");
497  gSystem->Exit(0);
498 }
499 
506 {
507  // Looks like the module changer is availble only here.
508  for (ModuleChanges::iterator i = m_scheduledChanges.begin(),
509  e = m_scheduledChanges.end();
510  i != e; ++i)
511  {
512  try {
513  moduleChanger()->changeModule(i->first, i->second);
514  }
515  catch (cms::Exception const& e)
516  {
517  fwLog(fwlog::kError) << "FWFFLooper::endOfLoop caught exception.\n";
518  std::cerr << e.what() << std::endl;
519  }
520  }
521  m_scheduledChanges.clear();
522  return kContinue;
523 }
524 
525 void
526 FWFFLooper::showPathsGUI(const TGWindow *)
527 {
528  if (!m_pathsGUI)
529  return;
530  if (m_pathsGUI->IsMapped())
531  {
532  guiManager()->setFilterButtonText("Show paths / CMSSW configuration editor");
533  m_pathsGUI->UnmapWindow();
534  }
535  else
536  {
537  guiManager()->setFilterButtonText("Hide paths / CMSSW configuration editor");
538  m_pathsGUI->MapWindow();
539  }
540 }
541 
542 void
544 {
545  m_scheduledChanges[moduleLabel] = ps;
546 }
547 
548 //______________________________________________________________________________
549 
550 void
552 {
553  fwLog(fwlog::kInfo) << "FWFFLooper set TGeo geomtery from DisplayGeomRecord.\n";
554 
556  dgRec.get(geom);
557  TEveGeoManagerHolder _tgeo(const_cast<TGeoManager*>(geom.product()));
559 }
TEveMagField * getMagField()
Definition: FWFFLooper.cc:476
std::optional< eventsetup::EventSetupRecordGeneric > find(const eventsetup::EventSetupRecordKey &iKey) const
Definition: EventSetup.h:160
edm::EDLooperBase::Status endOfLoop(const edm::EventSetup &, unsigned int) override
Definition: FWFFLooper.cc:505
bool getByLabel(std::string const &label, Handle< PROD > &result) const
Definition: Run.h:280
T getUntrackedParameter(std::string const &, T const &) const
void preModuleEvent(edm::StreamContext const &, edm::ModuleCallingContext const &)
static const TGPicture * info(bool iBackgroundIsBlack)
void setupFieldForPropagator(TEveTrackPropagator *prop)
Definition: FWFFLooper.cc:482
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
void watchPreModuleEvent(PreModuleEvent::slot_type const &iSlot)
void autoLoadNewEvent() override
Definition: FWFFLooper.cc:276
#define nullptr
void startingNewLoop(unsigned int) override
Definition: FWFFLooper.cc:220
void watchPostModuleEvent(PostModuleEvent::slot_type const &iSlot)
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:2
void attachTo(edm::ActivityRegistry &) override
Override this method if you need to monitor the state of the processing.
Definition: FWFFLooper.cc:200
char const * what() const override
Definition: Exception.cc:103
void postEndJob()
Definition: FWFFLooper.cc:244
void remakeGeometry(const DisplayGeomRecord &dgRec)
Definition: FWFFLooper.cc:551
FWFFLooper(const edm::ParameterSet &)
void loadDefaultGeometryFile(void)
Definition: FWFFLooper.cc:192
Definition: Electron.h:6
void quit() override
Definition: FWFFLooper.cc:488
void requestChanges(const std::string &, const edm::ParameterSet &)
Definition: FWFFLooper.cc:543
FWRecoGeom::InfoMap idToName
edm::EDLooperBase::Status duringLoop(const edm::Event &, const edm::EventSetup &, edm::ProcessingController &) override
Definition: FWFFLooper.cc:392
void display(const std::string &info="")
Definition: FWFFLooper.cc:459
void setTransitionToEvent(edm::EventID const &iID)
def draw(name, histos, styles=_defaultStyles, legendLabels=[], kwargs)
virtual void stopPlaying()
ProductT const & get(ESGetToken< ProductT, DepRecordT > const &iToken) const
ForwardState forwardState() const
Returns the present state of processing.
void beginRun(const edm::Run &, const edm::EventSetup &) override
Definition: FWFFLooper.cc:311
T sqrt(T t)
Definition: SSEVec.h:18
T Abs(T a)
Definition: MathUtil.h:49
double f[11][100]
bool isValid() const
Definition: HandleBase.h:74
void checkPosition() override
Definition: FWFFLooper.cc:251
TRint * m_Rint
Definition: FWFFHelper.h:18
T const & get(Event const &event, InputTag const &tag)(false)
Definition: Event.h:658
#define fwLog(_level_)
Definition: fwLog.h:50
~FWFFLooper() override
Definition: FWFFLooper.cc:209
void postModuleEvent(edm::StreamContext const &, edm::ModuleCallingContext const &)
float m_avg_current
Definition: RunInfo.h:29
HLT enums.
void stopPlaying() override
Definition: FWFFLooper.cc:297
boost::function0< void > TaskFunctor
void showEventFilterGUI()
T get() const
Definition: EventSetup.h:71
static void setGeoManagerRuntime(TGeoManager *)
void showPathsGUI(const TGWindow *p)
Definition: FWFFLooper.cc:526
T const * product() const
Definition: ESHandle.h:86
ReverseState reverseState() const
Definition: event.py:1
Definition: Run.h:45