mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 23:20:29 -05:00
* Select top level summary cases and ensembles for reload Simplifies the summary case reloading process by removing the unnecessary `createAddressObjects` parameter and instead using the `showTreeNodes` flag to determine when to create address objects. This change optimizes the loading process, especially for ensembles, by avoiding the creation of addresses for all cases, which improves performance. It also moves the responsibility of building tree nodes into a dedicated function `buildTreeNodesIfRequired` which is only called when needed. * Remove obsolete parallel loop * Use zoomAll * Add updateConnectedEditors to make sure the tree nodes are updated correctly
527 lines
19 KiB
C++
527 lines
19 KiB
C++
/////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2016- Statoil ASA
|
|
//
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
|
// for more details.
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "RimSummaryCase.h"
|
|
|
|
#include "RiaEnsembleNameTools.h"
|
|
|
|
#include "RicfCommandObject.h"
|
|
#include "RifSummaryReaderInterface.h"
|
|
|
|
#include "RimProject.h"
|
|
#include "RimSummaryAddressCollection.h"
|
|
#include "RimSummaryEnsemble.h"
|
|
|
|
#include "cafCmdFeatureMenuBuilder.h"
|
|
#include "cafPdmFieldScriptingCapability.h"
|
|
#include "cafPdmUiCheckBoxEditor.h"
|
|
#include "cafPdmUiTreeAttributes.h"
|
|
#include "cafPdmUiTreeOrdering.h"
|
|
|
|
CAF_PDM_ABSTRACT_SOURCE_INIT( RimSummaryCase, "SummaryCase" );
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimSummaryCase::RimSummaryCase()
|
|
: nameChanged( this )
|
|
{
|
|
CAF_PDM_InitScriptableObject( "Summary Case", ":/SummaryCase.svg", "", "The Base Class for all Summary Cases" );
|
|
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_displayName, "ShortName", "Display Name" );
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_displayNameOption, "NameSetting", "Name Setting" );
|
|
|
|
CAF_PDM_InitScriptableField( &m_showSubNodesInTree, "ShowSubNodesInTree", true, "Show Summary Data Sub-Tree" );
|
|
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_showSubNodesInTree );
|
|
|
|
CAF_PDM_InitScriptableField( &m_includeInAutoReload, "IncludeInAutoReload", false, "Include in Automatic Case Reloads" );
|
|
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_includeInAutoReload );
|
|
|
|
CAF_PDM_InitScriptableField( &m_useAutoShortName_OBSOLETE, "AutoShortyName", false, "Use Auto Display Name" );
|
|
m_useAutoShortName_OBSOLETE.xmlCapability()->setIOWritable( false );
|
|
m_useAutoShortName_OBSOLETE.uiCapability()->setUiHidden( true );
|
|
|
|
CAF_PDM_InitScriptableFieldNoDefault( &m_summaryHeaderFilename, "SummaryHeaderFilename", "Summary Header File" );
|
|
m_summaryHeaderFilename.uiCapability()->setUiReadOnly( true );
|
|
|
|
CAF_PDM_InitScriptableField( &m_caseId, "Id", -1, "Case ID" );
|
|
m_caseId.registerKeywordAlias( "CaseId" );
|
|
m_caseId.uiCapability()->setUiReadOnly( true );
|
|
m_caseId.capability<caf::PdmAbstractFieldScriptingCapability>()->setIOWriteable( false );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_dataVectorFolders, "DataVectorFolders", "Data Folders" );
|
|
m_dataVectorFolders = new RimSummaryAddressCollection();
|
|
m_dataVectorFolders.uiCapability()->setUiHidden( true );
|
|
m_dataVectorFolders.xmlCapability()->disableIO();
|
|
|
|
m_isObservedData = false;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimSummaryCase::summaryHeaderFilename() const
|
|
{
|
|
return m_summaryHeaderFilename().path();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::setSummaryHeaderFileName( const QString& fileName )
|
|
{
|
|
m_summaryHeaderFilename = fileName;
|
|
|
|
updateAutoShortName();
|
|
updateTreeItemName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimSummaryCase::isObservedData() const
|
|
{
|
|
return m_isObservedData;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimSummaryCase::showTreeNodes() const
|
|
{
|
|
return m_showSubNodesInTree();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::setShowTreeNodes( bool enable )
|
|
{
|
|
m_showSubNodesInTree = enable;
|
|
|
|
if ( m_showSubNodesInTree )
|
|
{
|
|
if ( auto reader = summaryReader() )
|
|
{
|
|
// If the reader has no result addresses, we need to build the metadata to populate the data vector folders
|
|
reader->createAddressesIfRequired();
|
|
}
|
|
}
|
|
|
|
updateConnectedEditors();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::setCaseRealizationParameters( const std::shared_ptr<RigCaseRealizationParameters>& crlParameters )
|
|
{
|
|
m_crlParameters = crlParameters;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
std::shared_ptr<RigCaseRealizationParameters> RimSummaryCase::caseRealizationParameters() const
|
|
{
|
|
return m_crlParameters;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimSummaryCase::hasCaseRealizationParameters() const
|
|
{
|
|
return m_crlParameters != nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimSummaryEnsemble* RimSummaryCase::ensemble() const
|
|
{
|
|
RimSummaryEnsemble* e = firstAncestorOrThisOfType<RimSummaryEnsemble>();
|
|
return e && e->isEnsemble() ? e : nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::copyFrom( const RimSummaryCase& rhs )
|
|
{
|
|
m_displayName = rhs.m_displayName;
|
|
m_useAutoShortName_OBSOLETE = rhs.m_useAutoShortName_OBSOLETE;
|
|
m_summaryHeaderFilename = rhs.m_summaryHeaderFilename;
|
|
m_isObservedData = rhs.m_isObservedData;
|
|
|
|
updateTreeItemName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Sorting operator for sets and maps. Sorts by summary case short name.
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimSummaryCase::operator<( const RimSummaryCase& rhs ) const
|
|
{
|
|
return caseName() < rhs.caseName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
|
|
{
|
|
if ( changedField == &m_displayNameOption )
|
|
{
|
|
updateAutoShortName();
|
|
nameChanged.send();
|
|
}
|
|
else if ( changedField == &m_displayName )
|
|
{
|
|
m_displayNameOption = RimCaseDisplayNameTools::DisplayName::CUSTOM;
|
|
updateTreeItemName();
|
|
nameChanged.send();
|
|
}
|
|
else if ( changedField == &m_showSubNodesInTree )
|
|
{
|
|
updateConnectedEditors();
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RifReaderRftInterface* RimSummaryCase::rftReader()
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimSummaryCase::errorMessagesFromReader()
|
|
{
|
|
return QString();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int RimSummaryCase::serialNumber()
|
|
{
|
|
auto reader = summaryReader();
|
|
return reader ? reader->serialNumber() : -1;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
|
|
{
|
|
appendMenuItems( menuBuilder, true );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder, bool showCurveCalculator ) const
|
|
{
|
|
menuBuilder << "RicShowDataSourcesForRealization";
|
|
menuBuilder.addSeparator();
|
|
|
|
menuBuilder.subMenuStart( "Import" );
|
|
menuBuilder << "RicImportSummaryCaseFeature";
|
|
menuBuilder << "RicImportSummaryCasesFeature";
|
|
menuBuilder << "RicImportSummaryGroupFeature";
|
|
menuBuilder << "RicImportEnsembleFeature";
|
|
menuBuilder.subMenuEnd();
|
|
menuBuilder << "RicCreateSummaryEnsembleFeature";
|
|
menuBuilder.addSeparator();
|
|
menuBuilder << "RicNewSummaryMultiPlotFeature";
|
|
menuBuilder << "RicOpenSummaryPlotEditorFeature";
|
|
menuBuilder << "RicAppendSummaryCurvesForSummaryCasesFeature";
|
|
menuBuilder << "RicAppendSummaryPlotsForSummaryCasesFeature";
|
|
menuBuilder.addSeparator();
|
|
menuBuilder << "RicImportGridModelFromSummaryCaseFeature";
|
|
|
|
if ( showCurveCalculator )
|
|
{
|
|
menuBuilder << "RicShowSummaryCurveCalculatorFeature";
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
caf::PdmFieldHandle* RimSummaryCase::userDescriptionField()
|
|
{
|
|
return &m_displayName;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::defineObjectEditorAttribute( QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
|
|
{
|
|
if ( auto* treeItemAttribute = dynamic_cast<caf::PdmUiTreeViewItemAttribute*>( attribute ) )
|
|
{
|
|
// The tooltip text is set in RimEnsembleStatisticsCase::calculate for ensemble statistics. Use the presens of tooltip to determine
|
|
// if the tag should be added.
|
|
if ( !uiToolTip().isEmpty() )
|
|
{
|
|
auto tag = caf::PdmUiTreeViewItemAttribute::createTag();
|
|
tag->icon = caf::IconProvider( ":/info.png" );
|
|
|
|
treeItemAttribute->tags.push_back( std::move( tag ) );
|
|
}
|
|
if ( m_includeInAutoReload() )
|
|
{
|
|
auto tag = caf::PdmUiTreeViewItemAttribute::createTag();
|
|
tag->icon = caf::IconProvider( ":/TimedRefresh.png" );
|
|
treeItemAttribute->tags.push_back( std::move( tag ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
|
{
|
|
uiOrdering.add( &m_displayName );
|
|
uiOrdering.add( &m_displayNameOption );
|
|
uiOrdering.add( &m_summaryHeaderFilename );
|
|
uiOrdering.add( &m_caseId );
|
|
if ( ensemble() )
|
|
{
|
|
uiOrdering.add( &m_showSubNodesInTree );
|
|
}
|
|
else
|
|
{
|
|
uiOrdering.add( &m_includeInAutoReload );
|
|
}
|
|
|
|
uiOrdering.skipRemainingFields( true );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/ )
|
|
{
|
|
if ( showTreeNodes() )
|
|
{
|
|
if ( m_dataVectorFolders->isEmpty() )
|
|
{
|
|
buildTreeNodesIfRequired();
|
|
}
|
|
m_dataVectorFolders->updateUiTreeOrdering( uiTreeOrdering );
|
|
}
|
|
|
|
uiTreeOrdering.skipRemainingChildren( true );
|
|
|
|
updateTreeItemName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::updateTreeItemName()
|
|
{
|
|
setUiName( displayCaseName() );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimSummaryCase::displayCaseName() const
|
|
{
|
|
return m_displayName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
QString RimSummaryCase::nativeCaseName() const
|
|
{
|
|
return caseName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
RimCaseDisplayNameTools::DisplayName RimSummaryCase::displayNameType() const
|
|
{
|
|
return m_displayNameOption();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
caf::AppEnum<RiaDefines::EclipseUnitSystem> RimSummaryCase::unitsSystem()
|
|
{
|
|
RifSummaryReaderInterface* reader = summaryReader();
|
|
if ( reader )
|
|
{
|
|
return reader->unitSystem();
|
|
}
|
|
return RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::setDisplayNameOption( RimCaseDisplayNameTools::DisplayName displayNameOption )
|
|
{
|
|
m_displayNameOption = displayNameOption;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::initAfterRead()
|
|
{
|
|
if ( m_caseId() == -1 )
|
|
{
|
|
RimProject::current()->assignCaseIdToSummaryCase( this );
|
|
}
|
|
|
|
if ( m_useAutoShortName_OBSOLETE )
|
|
{
|
|
m_displayNameOption = RimCaseDisplayNameTools::DisplayName::SHORT_CASE_NAME;
|
|
}
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::updateAutoShortName()
|
|
{
|
|
if ( m_displayNameOption == RimCaseDisplayNameTools::DisplayName::FULL_CASE_NAME )
|
|
{
|
|
m_displayName = caseName();
|
|
}
|
|
else if ( m_displayNameOption == RimCaseDisplayNameTools::DisplayName::SHORT_CASE_NAME )
|
|
{
|
|
if ( ensemble() )
|
|
{
|
|
m_displayName = RiaEnsembleNameTools::uniqueShortNameForEnsembleCase( this );
|
|
}
|
|
else
|
|
{
|
|
m_displayName = RiaEnsembleNameTools::uniqueShortNameForSummaryCase( this );
|
|
}
|
|
}
|
|
updateTreeItemName();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
bool RimSummaryCase::includeInAutoReload() const
|
|
{
|
|
return m_includeInAutoReload;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::setCaseId( int caseId )
|
|
{
|
|
m_caseId = caseId;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
int RimSummaryCase::caseId() const
|
|
{
|
|
return m_caseId();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::setCustomCaseName( const QString& caseName )
|
|
{
|
|
m_displayNameOption = RimCaseDisplayNameTools::DisplayName::CUSTOM;
|
|
m_displayName = caseName;
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::buildTreeNodesIfRequired()
|
|
{
|
|
m_dataVectorFolders->deleteChildren();
|
|
|
|
if ( !showTreeNodes() ) return;
|
|
|
|
RifSummaryReaderInterface* reader = summaryReader();
|
|
if ( !reader ) return;
|
|
|
|
auto addresses = reader->allResultAddresses();
|
|
m_dataVectorFolders->updateFolderStructure( addresses, m_caseId );
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
///
|
|
//--------------------------------------------------------------------------------------------------
|
|
void RimSummaryCase::onCalculationUpdated()
|
|
{
|
|
// NB! Performance critical method
|
|
if ( !m_showSubNodesInTree ) return;
|
|
|
|
if ( m_dataVectorFolders->isEmpty() )
|
|
{
|
|
// Build the child nodes if they are not already built. This function will also create the
|
|
// calculated objects so we can do a early return.
|
|
buildTreeNodesIfRequired();
|
|
updateConnectedEditors();
|
|
|
|
return;
|
|
}
|
|
|
|
// Delete all calculated address objects
|
|
auto deletedCalculatedObjectCount = m_dataVectorFolders->deleteCalculatedAddresses();
|
|
int calculatedAddressCount = 0;
|
|
|
|
if ( auto reader = summaryReader() )
|
|
{
|
|
auto addresses = reader->allResultAddresses();
|
|
|
|
std::set<RifEclipseSummaryAddress> calculatedAddresses;
|
|
|
|
for ( const auto& adr : addresses )
|
|
{
|
|
if ( adr.isCalculated() )
|
|
{
|
|
calculatedAddresses.insert( adr );
|
|
}
|
|
}
|
|
|
|
calculatedAddressCount = static_cast<int>( calculatedAddresses.size() );
|
|
|
|
m_dataVectorFolders->updateFolderStructure( calculatedAddresses, m_caseId );
|
|
}
|
|
|
|
if ( deletedCalculatedObjectCount > 0 || calculatedAddressCount > 0 )
|
|
{
|
|
updateConnectedEditors();
|
|
}
|
|
}
|