Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:27:11

0001 // -*- C++ -*-
0002 //
0003 // Package:     Core
0004 // Class  :     FWEveView
0005 //
0006 // Implementation:
0007 //     [Notes on implementation]
0008 //
0009 // Original Author:  Alja Mrak-Tadel
0010 //         Created:  Thu Mar 16 14:11:32 CET 2010
0011 //
0012 
0013 #include <RVersion.h>
0014 #include <functional>
0015 #include <stdexcept>
0016 #include <string>
0017 
0018 // user include files
0019 
0020 #include "TGLOrthoCamera.h"
0021 #include "TGLPerspectiveCamera.h"
0022 #include "TGLCameraGuide.h"
0023 
0024 #include "TGLEmbeddedViewer.h"
0025 #include "TGLScenePad.h"
0026 #include "TEveManager.h"
0027 #include "TEveElement.h"
0028 #include "TEveWindow.h"
0029 #include "TEveScene.h"
0030 #include "TEveCalo.h"
0031 #include "TGLOverlay.h"
0032 
0033 #include "Fireworks/Core/interface/FWTEveViewer.h"
0034 #include "Fireworks/Core/interface/FWTGLViewer.h"
0035 
0036 #include "Fireworks/Core/interface/FWEveView.h"
0037 #include "Fireworks/Core/interface/FWViewType.h"
0038 #include "Fireworks/Core/interface/CmsShowViewPopup.h"
0039 #include "Fireworks/Core/interface/FWEventAnnotation.h"
0040 #include "Fireworks/Core/interface/CmsAnnotation.h"
0041 #include "Fireworks/Core/interface/FWGLEventHandler.h"
0042 #include "Fireworks/Core/interface/FWViewContextMenuHandlerGL.h"
0043 #include "Fireworks/Core/interface/FWConfiguration.h"
0044 #include "Fireworks/Core/interface/FWColorManager.h"
0045 #include "Fireworks/Core/interface/fwLog.h"
0046 #include "Fireworks/Core/interface/Context.h"
0047 #include "Fireworks/Core/interface/FWViewContext.h"
0048 #include "Fireworks/Core/interface/FWViewEnergyScale.h"
0049 #include "Fireworks/Core/interface/CmsShowCommon.h"
0050 #include "Fireworks/Core/interface/FWViewEnergyScaleEditor.h"
0051 
0052 namespace fireworks {
0053   class Context;
0054 }
0055 
0056 /* This class is temporary workaround for missing in TGLAnnotation functionality */
0057 class ScaleAnnotation : public TGLAnnotation {
0058 public:
0059   ScaleAnnotation(TGLViewerBase* parent, const char* text, Float_t posx, Float_t posy)
0060       : TGLAnnotation(parent, text, posx, posy) {}
0061   ~ScaleAnnotation() override {}
0062 
0063   void setText(const char* txt) { fText = txt; }
0064 };
0065 
0066 //
0067 // constructors and destructor
0068 //
0069 
0070 FWEveView::FWEveView(TEveWindowSlot* iParent, FWViewType::EType type, unsigned int version)
0071     : FWViewBase(type, version),
0072       m_context(nullptr),
0073       m_viewer(nullptr),
0074       m_eventScene(nullptr),
0075       m_ownedProducts(nullptr),
0076       m_geoScene(nullptr),
0077       m_overlayEventInfo(nullptr),
0078       m_overlayLogo(nullptr),
0079       m_energyMaxValAnnotation(nullptr),
0080       m_cameraGuide(nullptr),
0081 // style
0082 #if ROOT_VERSION_CODE >= ROOT_VERSION(5, 26, 0)
0083       m_imageScale(this, "Image Scale", 1.0, 1.0, 6.0),
0084 #endif
0085       m_eventInfoLevel(this, "Overlay Event Info", 0l, 0l, 2l),
0086       m_drawCMSLogo(this, "Show Logo", false),
0087       m_pointSmooth(this, "Smooth points", false),
0088       m_pointSize(this, "Point size", 1.0, 1.0, 10.0),
0089       m_lineSmooth(this, "Smooth lines", false),
0090       m_lineWidth(this, "Line width", 1.0, 1.0, 10.0),
0091       m_lineOutlineScale(this, "Outline width scale", 1.0, 0.01, 10.0),
0092       m_lineWireframeScale(this, "Wireframe width scale", 1.0, 0.01, 10.0),
0093       m_showCameraGuide(this, "Show Camera Guide", false),
0094       m_useGlobalEnergyScale(this, "UseGlobalEnergyScale", true),
0095       m_viewContext(new FWViewContext()),
0096       m_localEnergyScale(new FWViewEnergyScale(FWViewType::idToName(type), version)),
0097       m_viewEnergyScaleEditor(nullptr) {
0098   m_viewer = new FWTEveViewer(typeName().c_str());
0099 
0100   FWTGLViewer* embeddedViewer = m_viewer->SpawnFWTGLViewer();
0101   iParent->ReplaceWindow(m_viewer);
0102   gEve->GetViewers()->AddElement(m_viewer);
0103 
0104   m_eventScene = gEve->SpawnNewScene(Form("EventScene %s", typeName().c_str()));
0105   m_ownedProducts = new TEveElementList("ViewSpecificProducts");
0106   m_eventScene->AddElement(m_ownedProducts);
0107 
0108   m_viewer->AddScene(m_eventScene);
0109 
0110   // spawn geo scene
0111   m_geoScene = gEve->SpawnNewScene(Form("GeoScene %s", typeName().c_str()));
0112   m_geoScene->GetGLScene()->SetSelectable(kFALSE);
0113   m_viewer->AddScene(m_geoScene);
0114 
0115   FWGLEventHandler* eh = new FWGLEventHandler((TGWindow*)embeddedViewer->GetGLWidget(), (TObject*)embeddedViewer);
0116   embeddedViewer->SetEventHandler(eh);
0117   eh->setViewer(this);
0118   eh->openSelectedModelContextMenu_.connect(openSelectedModelContextMenu_);
0119   eh->SetDoInternalSelection(kFALSE);
0120   FWViewContextMenuHandlerGL* ctxHand = new FWViewContextMenuHandlerGL(this);
0121   // ctxHand->setPickCameraCenter(true);
0122   m_viewContextMenu.reset(ctxHand);
0123 
0124   m_energyMaxValAnnotation = new ScaleAnnotation(viewerGL(), "empty", 0.1, 0.9);
0125   m_energyMaxValAnnotation->SetRole(TGLOverlayElement::kViewer);
0126   m_energyMaxValAnnotation->SetState(TGLOverlayElement::kInvisible);
0127   m_energyMaxValAnnotation->SetUseColorSet(false);
0128   m_energyMaxValAnnotation->SetTextSize(0.05);
0129   m_energyMaxValAnnotation->SetTextColor(kMagenta);
0130 
0131   // style params
0132 
0133   m_overlayEventInfo = new FWEventAnnotation(embeddedViewer);
0134   m_overlayEventInfo->setLevel(0);
0135 
0136   m_eventInfoLevel.addEntry(0, "Nothing");
0137   m_eventInfoLevel.addEntry(1, "Run / event");
0138   m_eventInfoLevel.addEntry(2, "Run / event / lumi");
0139   m_eventInfoLevel.addEntry(3, "Full");
0140   m_eventInfoLevel.changed_.connect(std::bind(&FWEventAnnotation::setLevel, m_overlayEventInfo, std::placeholders::_1));
0141 
0142   m_overlayLogo = new CmsAnnotation(embeddedViewer, 0.02, 0.98);
0143   m_overlayLogo->setVisible(false);
0144   m_drawCMSLogo.changed_.connect(std::bind(&CmsAnnotation::setVisible, m_overlayLogo, std::placeholders::_1));
0145 
0146   m_cameraGuide = new TGLCameraGuide(0.9, 0.1, 0.08);
0147   m_cameraGuide->SetState(TGLOverlayElement::kInvisible);
0148   embeddedViewer->AddOverlayElement(m_cameraGuide);
0149   m_showCameraGuide.changed_.connect(std::bind(&FWEveView::cameraGuideChanged, this));
0150 
0151   m_pointSmooth.changed_.connect(std::bind(&FWEveView::pointLineScalesChanged, this));
0152   m_pointSize.changed_.connect(std::bind(&FWEveView::pointLineScalesChanged, this));
0153   m_lineSmooth.changed_.connect(std::bind(&FWEveView::pointLineScalesChanged, this));
0154   m_lineWidth.changed_.connect(std::bind(&FWEveView::pointLineScalesChanged, this));
0155   m_lineOutlineScale.changed_.connect(std::bind(&FWEveView::pointLineScalesChanged, this));
0156   m_lineWireframeScale.changed_.connect(std::bind(&FWEveView::pointLineScalesChanged, this));
0157 
0158   // create scale for view  ..
0159   m_viewContext->setEnergyScale(m_localEnergyScale.get());
0160   m_useGlobalEnergyScale.changed_.connect(std::bind(&FWEveView::useGlobalEnergyScaleChanged, this));
0161   m_localEnergyScale->parameterChanged_.connect(std::bind(&FWEveView::setupEnergyScale, this));
0162 }
0163 
0164 FWEveView::~FWEveView() {
0165   m_geoScene->RemoveElements();
0166   m_eventScene->RemoveElements();
0167   m_viewer->DestroyWindowAndSlot();
0168 }
0169 
0170 //______________________________________________________________________________
0171 // const member functions
0172 
0173 FWViewContextMenuHandlerBase* FWEveView::contextMenuHandler() const {
0174   return dynamic_cast<FWViewContextMenuHandlerBase*>(m_viewContextMenu.get());
0175 }
0176 
0177 TGLViewer* FWEveView::viewerGL() const { return m_viewer->GetGLViewer(); }
0178 
0179 TEveViewer* FWEveView::viewer() { return m_viewer; }
0180 
0181 FWTGLViewer* FWEveView::fwViewerGL() const { return m_viewer->fwGlViewer(); }
0182 
0183 void FWEveView::saveImageTo(const std::string& iName) const {
0184   bool succeeded = false;
0185 #if ROOT_VERSION_CODE >= ROOT_VERSION(5, 26, 0)
0186   succeeded = viewerGL()->SavePictureScale(iName, m_imageScale.value());
0187 #else
0188   succeeded = viewerGL()->SavePicture(iName.c_str());
0189 #endif
0190 
0191   if (!succeeded) {
0192     throw std::runtime_error("Unable to save picture");
0193   }
0194   fwLog(fwlog::kInfo) << "Saved image " << iName << std::endl;
0195 }
0196 
0197 //-------------------------------------------------------------------------------
0198 void FWEveView::pointLineScalesChanged() {
0199   viewerGL()->SetSmoothPoints(m_pointSmooth.value());
0200   viewerGL()->SetPointScale(m_pointSize.value());
0201   viewerGL()->SetSmoothLines(m_lineSmooth.value());
0202   viewerGL()->SetLineScale(m_lineWidth.value());
0203   viewerGL()->SetOLLineW(m_lineOutlineScale.value());
0204   viewerGL()->SetWFLineW(m_lineWireframeScale.value());
0205   viewerGL()->Changed();
0206   gEve->Redraw3D();
0207 }
0208 
0209 void FWEveView::cameraGuideChanged() {
0210   m_cameraGuide->SetBinaryState(m_showCameraGuide.value());
0211   viewerGL()->Changed();
0212   gEve->Redraw3D();
0213 }
0214 
0215 void FWEveView::eventBegin() {}
0216 
0217 void FWEveView::eventEnd() {
0218   m_overlayEventInfo->setEvent();
0219   setupEnergyScale();
0220 }
0221 
0222 void FWEveView::setBackgroundColor(Color_t iColor) { FWColorManager::setColorSetViewer(viewerGL(), iColor); }
0223 
0224 void FWEveView::resetCamera() { viewerGL()->ResetCurrentCamera(); }
0225 
0226 //______________________________________________________________________________
0227 void FWEveView::setContext(const fireworks::Context& x) {
0228   m_context = &x;
0229 
0230   // in constructor view context has local scale
0231   if (m_useGlobalEnergyScale.value())
0232     m_viewContext->setEnergyScale(context().commonPrefs()->getEnergyScale());
0233 }
0234 
0235 bool FWEveView::isEnergyScaleGlobal() const { return m_useGlobalEnergyScale.value(); }
0236 
0237 void FWEveView::useGlobalEnergyScaleChanged() {
0238   m_viewContext->setEnergyScale(m_useGlobalEnergyScale.value() ? context().commonPrefs()->getEnergyScale()
0239                                                                : m_localEnergyScale.get());
0240   if (m_viewEnergyScaleEditor)
0241     m_viewEnergyScaleEditor->setEnabled(!m_useGlobalEnergyScale.value());
0242   setupEnergyScale();
0243 }
0244 
0245 void FWEveView::voteCaloMaxVal() {
0246   TEveCaloViz* calo = getEveCalo();
0247   if (calo)
0248     context().voteMaxEtAndEnergy(calo->GetData()->GetMaxVal(true), calo->GetData()->GetMaxVal(false));
0249 }
0250 
0251 void FWEveView::setupEnergyScale() {
0252   // Called at end of event OR if scale parameters changed.
0253 
0254   FWViewEnergyScale* energyScale = viewContext()->getEnergyScale();
0255   // printf("setupEnergyScale %s >> scale name %s\n", typeName().c_str(), energyScale->name().c_str());
0256   voteCaloMaxVal();
0257 
0258   // set cache for energy to lenght conversion
0259   float maxVal = context().getMaxEnergyInEvent(energyScale->getPlotEt());
0260   energyScale->updateScaleFactors(maxVal);
0261   // printf("max event val %f \n", maxVal);
0262   // printf("scales lego %f \n",  energyScale->getScaleFactorLego());
0263 
0264   // configure TEveCaloViz
0265   TEveCaloViz* calo = getEveCalo();
0266   if (calo) {
0267     calo->SetPlotEt(energyScale->getPlotEt());
0268     if (FWViewType::isLego(typeId())) {
0269       float f = energyScale->getScaleFactorLego();
0270       calo->SetMaxValAbs(TMath::Pi() / f);
0271     } else {
0272       float f = energyScale->getScaleFactor3D();
0273       calo->SetMaxValAbs(100 / f);
0274     }
0275     calo->ElementChanged();
0276   }
0277 
0278   // emit signal to proxy builders
0279   viewContext()->scaleChanged();
0280   gEve->Redraw3D();
0281 }
0282 
0283 void FWEveView::setupEventCenter() {
0284   // piggyback on scales signal connections to redraw jets
0285   // can add new signal in future if necessary
0286   viewContext()->scaleChanged();
0287   gEve->Redraw3D();
0288 }
0289 
0290 //-------------------------------------------------------------------------------
0291 void FWEveView::addTo(FWConfiguration& iTo) const {
0292   // take care of parameters
0293   FWConfigurableParameterizable::addTo(iTo);
0294 
0295   {
0296     assert(m_overlayEventInfo);
0297     m_overlayEventInfo->addTo(iTo);
0298   }
0299   {
0300     assert(m_overlayLogo);
0301     m_overlayLogo->addTo(iTo);
0302   }
0303 
0304   m_viewContext->getEnergyScale()->addTo(iTo);
0305 }
0306 
0307 void FWEveView::setFrom(const FWConfiguration& iFrom) {
0308   // Make sure you change the version ranges here
0309   // whenever you update the logic.
0310   // The rationale should be:
0311   // (version range supported by the next block) && (version range in the configuration file)
0312   //
0313   // This is not "forward" compatible, but I don't think
0314   // we care.
0315   if (version() >= 2 && iFrom.version() >= 1) {
0316     for (const_iterator it = begin(), itEnd = end(); it != itEnd; ++it) {
0317       (*it)->setFrom(iFrom);
0318     }
0319   }
0320   if (iFrom.version() > 1) {
0321     assert(m_overlayEventInfo);
0322     m_overlayEventInfo->setFrom(iFrom);
0323   }
0324   {
0325     assert(m_overlayLogo);
0326     m_overlayLogo->setFrom(iFrom);
0327   }
0328 
0329   if (iFrom.version() > 4) {
0330     m_localEnergyScale->setFrom(iFrom);
0331   }
0332 
0333   // selection clors
0334   {
0335     const TGLColorSet& lcs = context().commonPrefs()->getLightColorSet();
0336     const TGLColorSet& dcs = context().commonPrefs()->getDarkColorSet();
0337     const UChar_t* ca = nullptr;
0338 
0339     ca = lcs.Selection(1).CArr();
0340     viewerGL()->RefLightColorSet().Selection(1).SetColor(ca[0], ca[1], ca[2]);
0341     ca = lcs.Selection(3).CArr();
0342     viewerGL()->RefLightColorSet().Selection(3).SetColor(ca[0], ca[1], ca[2]);
0343     ca = dcs.Selection(1).CArr();
0344     viewerGL()->RefDarkColorSet().Selection(1).SetColor(ca[0], ca[1], ca[2]);
0345     ca = dcs.Selection(3).CArr();
0346     viewerGL()->RefDarkColorSet().Selection(3).SetColor(ca[0], ca[1], ca[2]);
0347   }
0348 }
0349 
0350 //______________________________________________________________________________
0351 
0352 void FWEveView::addToOrthoCamera(TGLOrthoCamera* camera, FWConfiguration& iTo) const {
0353   // zoom
0354   std::string name("cameraZoom");
0355   iTo.addKeyValue(name + typeName(), FWConfiguration(std::to_string(camera->GetZoom())));
0356 
0357   // transformation matrix
0358   std::string matrixName("cameraMatrix");
0359   for (unsigned int i = 0; i < 16; ++i) {
0360     std::ostringstream osIndex;
0361     osIndex << i;
0362     std::ostringstream osValue;
0363     osValue << camera->GetCamTrans()[i];
0364     iTo.addKeyValue(matrixName + osIndex.str() + typeName(), FWConfiguration(osValue.str()));
0365   }
0366 }
0367 
0368 void FWEveView::setFromOrthoCamera(TGLOrthoCamera* camera, const FWConfiguration& iFrom) {
0369   try {
0370     // zoom
0371     std::string zoomName("cameraZoom");
0372     zoomName += typeName();
0373     if (iFrom.valueForKey(zoomName) == nullptr) {
0374       throw std::runtime_error("can't restore parameter cameraZoom");
0375     }
0376     camera->SetZoom(std::stod(iFrom.valueForKey(zoomName)->value()));
0377 
0378     // transformation matrix
0379     std::string matrixName("cameraMatrix");
0380     for (unsigned int i = 0; i < 16; ++i) {
0381       std::ostringstream os;
0382       os << i;
0383       const FWConfiguration* value = iFrom.valueForKey(matrixName + os.str() + typeName());
0384       if (value == nullptr) {
0385         throw std::runtime_error("can't restore parameter cameraMatrix.");
0386       }
0387       std::istringstream s(value->value());
0388       s >> (camera->RefCamTrans()[i]);
0389     }
0390   } catch (const std::runtime_error& iException) {
0391     fwLog(fwlog::kInfo) << "Caught exception while restoring camera parameters in view " << typeName() << "\n.";
0392     viewerGL()->ResetCamerasAfterNextUpdate();
0393   }
0394   camera->IncTimeStamp();
0395 }
0396 
0397 void FWEveView::addToPerspectiveCamera(TGLPerspectiveCamera* cam, const std::string& name, FWConfiguration& iTo) const {
0398   // transformation matrix
0399   std::string matrixName("cameraMatrix");
0400   for (unsigned int i = 0; i < 16; ++i) {
0401     std::ostringstream osIndex;
0402     osIndex << i;
0403     std::ostringstream osValue;
0404     osValue << (cam->GetCamTrans())[i];
0405     iTo.addKeyValue(matrixName + osIndex.str() + name, FWConfiguration(osValue.str()));
0406   }
0407 
0408   // transformation matrix base
0409   matrixName = "cameraMatrixBase";
0410   for (unsigned int i = 0; i < 16; ++i) {
0411     std::ostringstream osIndex;
0412     osIndex << i;
0413     std::ostringstream osValue;
0414     osValue << (cam->GetCamBase())[i];
0415     iTo.addKeyValue(matrixName + osIndex.str() + name, FWConfiguration(osValue.str()));
0416   }
0417   { iTo.addKeyValue(name + " FOV", FWConfiguration(std::to_string(cam->GetFOV()))); }
0418 }
0419 
0420 void FWEveView::setFromPerspectiveCamera(TGLPerspectiveCamera* cam,
0421                                          const std::string& name,
0422                                          const FWConfiguration& iFrom) {
0423   try {
0424     std::string matrixName("cameraMatrix");
0425     for (unsigned int i = 0; i < 16; ++i) {
0426       std::ostringstream os;
0427       os << i;
0428       const FWConfiguration* value = iFrom.valueForKey(matrixName + os.str() + name);
0429       if (value == nullptr) {
0430         throw std::runtime_error("can't restore parameter cameraMatrix.");
0431       }
0432       std::istringstream s(value->value());
0433       s >> ((cam->RefCamTrans())[i]);
0434     }
0435 
0436     // transformation matrix base
0437     matrixName = "cameraMatrixBase";
0438     for (unsigned int i = 0; i < 16; ++i) {
0439       std::ostringstream os;
0440       os << i;
0441       const FWConfiguration* value = iFrom.valueForKey(matrixName + os.str() + name);
0442       if (value == nullptr) {
0443         throw std::runtime_error("can't restore parameter cameraMatrixBase.");
0444       }
0445 
0446       std::istringstream s(value->value());
0447       s >> ((cam->RefCamBase())[i]);
0448     }
0449 
0450     {
0451       const FWConfiguration* value = iFrom.valueForKey(name + " FOV");
0452       if (value == nullptr) {
0453         throw std::runtime_error("can't restore parameter cameraMatrixBase.");
0454       }
0455       cam->SetFOV(std::stod(value->value()));
0456     }
0457 
0458     cam->IncTimeStamp();
0459   } catch (const std::runtime_error& iException) {
0460     fwLog(fwlog::kInfo) << "Caught exception while restoring camera parameters in view " << typeName() << "\n.";
0461     viewerGL()->ResetCamerasAfterNextUpdate();
0462     fwLog(fwlog::kDebug) << "Reset camera fo view " << typeName() << "\n.";
0463   }
0464 }
0465 
0466 void FWEveView::populateController(ViewerParameterGUI& gui) const {
0467   gui.requestTab("Style")
0468       .addParam(&m_eventInfoLevel)
0469       .addParam(&m_drawCMSLogo)
0470       .addParam(&m_showCameraGuide)
0471       .separator()
0472       .
0473 #if ROOT_VERSION_CODE >= ROOT_VERSION(5, 26, 0)
0474       addParam(&m_imageScale)
0475       .
0476 #endif
0477       addParam(&m_pointSize)
0478       .addParam(&m_pointSmooth)
0479       .addParam(&m_lineSmooth)
0480       .addParam(&m_lineWidth)
0481       .addParam(&m_lineOutlineScale)
0482       .addParam(&m_lineWireframeScale);
0483 
0484   gui.requestTab("Scales").addParam(&m_useGlobalEnergyScale);
0485 
0486   m_viewEnergyScaleEditor =
0487       new FWViewEnergyScaleEditor(m_localEnergyScale.get(), gui.getTabContainer(), !FWViewType::isLego(typeId()));
0488   m_viewEnergyScaleEditor->setEnabled(!m_useGlobalEnergyScale.value());
0489   gui.addFrameToContainer(m_viewEnergyScaleEditor);
0490 }