Files
ResInsight/ApplicationLibCode/UserInterface/RiuSummaryVectorSelectionUi.cpp
T
Magne Sjaastad a94c1235c6 #13715 RiuSummaryVectorSelectionUi: Create addresses for all realizations in Plot Editor
For ensemble member cases used as individual sources in the Plot Editor,
createAddressesIfRequired() was never called, causing allResultAddresses()
to return an empty set for all non-representative realizations.
2026-03-10 11:56:38 +01:00

1557 lines
70 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017 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 "RiuSummaryVectorSelectionUi.h"
#include "RiaCurveSetDefinition.h"
#include "RiaOptionItemFactory.h"
#include "RiaStdStringTools.h"
#include "Summary/RiaSummaryCurveDefinition.h"
#include "Summary/RiaSummaryDefines.h"
#include "RifEclipseSummaryAddress.h"
#include "RifReaderEclipseSummary.h"
#include "RifSummaryReaderInterface.h"
#include "RimObservedDataCollection.h"
#include "RimObservedSummaryData.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimSummaryCalculation.h"
#include "RimSummaryCalculationCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryEnsemble.h"
#include "RiuSummaryCurveDefinitionKeywords.h"
#include "RiuSummaryQuantityNameInfoProvider.h"
#include "cafPdmPointer.h"
#include "cafPdmUiFieldHandle.h"
#include "cafPdmUiTreeSelectionEditor.h"
#include <QDebug>
#include <algorithm>
using namespace RifEclipseSummaryAddressDefines;
CAF_PDM_SOURCE_INIT( RiuSummaryVectorSelectionUi, "RicSummaryAddressSelection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
class SummaryIdentifierAndField
{
public:
SummaryIdentifierAndField()
: m_summaryIdentifier( (SummaryIdentifierType)0 )
, m_pdmField( nullptr )
{
}
SummaryIdentifierAndField( const SummaryIdentifierAndField& ) = delete;
SummaryIdentifierAndField( SummaryIdentifierType summaryIdentifier )
: m_summaryIdentifier( summaryIdentifier )
, m_pdmField( new caf::PdmField<std::vector<QString>>() )
{
}
virtual ~SummaryIdentifierAndField();
SummaryIdentifierType summaryIdentifier() const { return m_summaryIdentifier; }
caf::PdmField<std::vector<QString>>* pdmField() { return m_pdmField; }
private:
SummaryIdentifierType m_summaryIdentifier;
caf::PdmField<std::vector<QString>>* m_pdmField;
};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
SummaryIdentifierAndField::~SummaryIdentifierAndField()
{
delete m_pdmField;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryVectorSelectionUi::RiuSummaryVectorSelectionUi()
: m_identifierFieldsMap( {
{ SummaryCategory::SUMMARY_FIELD,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_AQUIFER,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_AQUIFER_NUMBER ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_NETWORK,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_NETWORK_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_MISC,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_REGION,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_REGION_NUMBER ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_REGION_2_REGION,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_REGION_2_REGION ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_GROUP,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_GROUP_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_WELL,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_WELL_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_WELL_CONNECTION,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_WELL_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_CELL_IJK ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_WELL_CONNECTION_LGR,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_LGR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_WELL_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_CELL_IJK ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_WELL_LGR,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_LGR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_WELL_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_WELL_SEGMENT,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_WELL_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_SEGMENT_NUMBER ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_WELL_COMPLETION,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_WELL_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_WELL_COMPLETION_NUMBER ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_BLOCK,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_CELL_IJK ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_BLOCK_LGR,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_LGR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_CELL_IJK ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
{ SummaryCategory::SUMMARY_IMPORTED,
{ new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_VECTOR_NAME ),
new SummaryIdentifierAndField( SummaryIdentifierType::INPUT_ID ) } },
} )
, m_showIndividualEnsembleCases( true )
{
CAF_PDM_InitFieldNoDefault( &m_selectedSources, "SummaryCases", "Cases" );
m_selectedSources.uiCapability()->setAutoAddingOptionFromValue( false );
CAF_PDM_InitFieldNoDefault( &m_currentSummaryCategory, "CurrentSummaryCategory", "Current Summary Category" );
CAF_PDM_InitFieldNoDefault( &m_selectedSummaryCategories, "SelectedSummaryCategories", "Summary Categories" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_FIELD][0]->pdmField(), "FieldVectors", "Field vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_FIELD][1]->pdmField(), "FieldCalculationIds", "Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_AQUIFER][0]->pdmField(), "Aquifers", "Aquifers" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_AQUIFER][1]->pdmField(), "AquiferVectors", "Aquifer Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_AQUIFER][2]->pdmField(),
"AquifierCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_NETWORK][0]->pdmField(), "NetworkNames", "Networks" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_NETWORK][1]->pdmField(), "NetworkVectors", "Network Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_NETWORK][2]->pdmField(),
"NetworkCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_MISC][0]->pdmField(), "MiscVectors", "Misc Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_MISC][1]->pdmField(), "MiscCalculationIds", "Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION][0]->pdmField(), "Regions", "Regions" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION][1]->pdmField(), "RegionsVectors", "Regions Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION][2]->pdmField(), "RegionCalculationIds", "Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION_2_REGION][0]->pdmField(),
"Region2RegionRegions",
"Regions" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION_2_REGION][1]->pdmField(),
"Region2RegionVectors",
"Region2s Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION_2_REGION][2]->pdmField(),
"Region2RegionCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_GROUP][0]->pdmField(), "WellGroupWellGroupNames", "Groups" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_GROUP][1]->pdmField(), "WellGroupVectors", "Well Group Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_GROUP][2]->pdmField(),
"WellGroupCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL][0]->pdmField(), "WellWellName", "Wells" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL][1]->pdmField(), "WellVectors", "Well Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL][2]->pdmField(), "WellCalculationIds", "Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION][0]->pdmField(),
"WellConnectionWellName",
"Wells" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION][1]->pdmField(), "WellConnectionIjk", "Cell IJK" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION][2]->pdmField(),
"WellConnectionVectors",
"Well Connection Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION][3]->pdmField(),
"WellConnectionCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][0]->pdmField(),
"WellConnectionLgrLgrName",
"LGR Names" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][1]->pdmField(),
"WellConnectionLgrWellName",
"Wells" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][2]->pdmField(),
"WellConnectionLgrIjk",
"Cell IJK" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][3]->pdmField(),
"WellConnectionLgrVectors",
"Well Completion Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][4]->pdmField(),
"WellConnectionLgrCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_LGR][0]->pdmField(), "WellLgrLgrName", "LGR Names" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_LGR][1]->pdmField(), "WellLgrWellName", "Wells" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_LGR][2]->pdmField(), "WellLgrVectors", "Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_LGR][3]->pdmField(),
"WellLgrCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_SEGMENT][0]->pdmField(), "WellSegmentWellName", "Wells" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_SEGMENT][1]->pdmField(), "WellSegmentNumber", "Segments" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_SEGMENT][2]->pdmField(), "WellSegmentVectors", "Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_SEGMENT][3]->pdmField(),
"WellSegmentCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_COMPLETION][0]->pdmField(),
"WellCompletionWellName",
"Wells" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_COMPLETION][1]->pdmField(),
"WellCompletionNumber",
"Completion Numbers" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_COMPLETION][2]->pdmField(),
"WellCompletionVectors",
"Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_COMPLETION][3]->pdmField(),
"WellCompletionCalculationIds",
"Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK][0]->pdmField(), "BlockIjk", "Cell IJK" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK][1]->pdmField(), "BlockVectors", "Block Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK][2]->pdmField(), "BlockCalculationIds", "Calculation Ids" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK_LGR][0]->pdmField(), "BlockLgrLgrName", "LGR Names" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK_LGR][1]->pdmField(), "BlockLgrIjk", "Cell IJK" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK_LGR][2]->pdmField(), "BlockLgrVectors", "Block Vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK_LGR][3]->pdmField(),
"BlockLgrCalculationIds",
"CalculationIds" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_IMPORTED][0]->pdmField(), "ImportedVectors", "Imported vectors" );
CAF_PDM_InitFieldNoDefault( m_identifierFieldsMap[SummaryCategory::SUMMARY_IMPORTED][1]->pdmField(),
"ImportedCalculationIds",
"Calculation Ids" );
for ( const auto& itemTypes : m_identifierFieldsMap )
{
for ( const auto& itemInputType : itemTypes.second )
{
itemInputType->pdmField()->uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
itemInputType->pdmField()->uiCapability()->setUiLabelPosition(
itemTypes.second.size() > 2 ? caf::PdmUiItemInfo::LabelPosition::TOP : caf::PdmUiItemInfo::LabelPosition::HIDDEN );
itemInputType->pdmField()->uiCapability()->setAutoAddingOptionFromValue( false );
}
itemTypes.second.back()->pdmField()->uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
}
m_selectedSources.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
m_selectedSources.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
m_selectedSources.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
m_selectedSummaryCategories.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
m_selectedSummaryCategories.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::HIDDEN );
m_currentSummaryCategory.uiCapability()->setUiHidden( true );
m_multiSelectionMode = false;
m_hideEnsembles = false;
m_hideSummaryCases = false;
m_hideDifferenceVectors = false;
m_hideHistoryVectors = false;
m_hideVectorsWithoutHistory = false;
m_hideCalculationIncompatibleCategories = false;
m_prevCurveCount = 0;
m_prevCurveSetCount = 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuSummaryVectorSelectionUi::~RiuSummaryVectorSelectionUi()
{
for ( const auto& identifierAndFieldList : m_identifierFieldsMap )
{
for ( const auto& identifierAndField : identifierAndFieldList.second )
{
delete identifierAndField;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RiaSummaryCurveDefinition> RiuSummaryVectorSelectionUi::allCurveDefinitionsFromSelection() const
{
std::vector<RiaSummaryCurveDefinition> curveDefVector;
{
std::set<RiaSummaryCurveDefinition> curveDefinitions;
std::set<RifEclipseSummaryAddress> selectedAddressesFromUi = buildAddressListFromSelections();
for ( SummarySource* currSource : selectedSummarySources() )
{
RimSummaryCase* sumCase = dynamic_cast<RimSummaryCase*>( currSource );
if ( sumCase == nullptr ) continue;
std::set<RifEclipseSummaryAddress> addressesFromSource;
std::vector<RimSummaryCase*> casesFromSource;
RifSummaryReaderInterface* reader = sumCase ? sumCase->summaryReader() : nullptr;
if ( reader )
{
addressesFromSource.insert( reader->allResultAddresses().begin(), reader->allResultAddresses().end() );
casesFromSource.push_back( sumCase );
}
for ( auto caseFromSource : casesFromSource )
{
for ( const auto& addressFromSource : addressesFromSource )
{
if ( selectedAddressesFromUi.count( addressFromSource ) > 0 )
{
curveDefinitions.insert( RiaSummaryCurveDefinition( caseFromSource, addressFromSource, false ) );
}
}
}
}
std::copy( curveDefinitions.begin(), curveDefinitions.end(), std::back_inserter( curveDefVector ) );
}
return curveDefVector;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RiaCurveSetDefinition> RiuSummaryVectorSelectionUi::allCurveSetDefinitionsFromSelections() const
{
std::vector<RiaCurveSetDefinition> curveSetDefVector;
std::set<RiaCurveSetDefinition> curveSetDefinitions;
std::set<RifEclipseSummaryAddress> selectedAddressesFromUi = buildAddressListFromSelections();
for ( SummarySource* currSource : selectedSummarySources() )
{
RimSummaryEnsemble* ensemble = dynamic_cast<RimSummaryEnsemble*>( currSource );
if ( !ensemble ) continue;
std::set<RifEclipseSummaryAddress> addressesFromSource;
// Build case list
auto addresses = ensemble->ensembleSummaryAddresses();
addressesFromSource.insert( addresses.begin(), addresses.end() );
for ( const auto& addressFromSource : addressesFromSource )
{
if ( selectedAddressesFromUi.count( addressFromSource ) > 0 )
{
curveSetDefinitions.insert( RiaCurveSetDefinition( ensemble, addressFromSource ) );
}
}
}
std::copy( curveSetDefinitions.begin(), curveSetDefinitions.end(), std::back_inserter( curveSetDefVector ) );
return curveSetDefVector;
}
//--------------------------------------------------------------------------------------------------
/// One CurveDefinition pr ensemble curve set,
/// but if enableIndividualEnsembleCaseSelection has been enabled,
/// the ensembles are never available for direct selection, and this method will always return the
/// "expanded" set of curvedefinitions
//--------------------------------------------------------------------------------------------------
std::vector<RiaSummaryCurveDefinition> RiuSummaryVectorSelectionUi::selection() const
{
std::vector<RiaSummaryCurveDefinition> curveDefSelection;
std::set<RifEclipseSummaryAddress> selectedAddressesFromUi = buildAddressListFromSelections();
for ( SummarySource* currSource : selectedSummarySources() )
{
RimSummaryEnsemble* ensemble = dynamic_cast<RimSummaryEnsemble*>( currSource );
RimSummaryCase* sourceCase = dynamic_cast<RimSummaryCase*>( currSource );
if ( ensemble )
{
std::set<RifEclipseSummaryAddress> addressUnion = ensemble->ensembleSummaryAddresses();
for ( const auto& addr : selectedAddressesFromUi )
{
if ( addressUnion.count( addr ) )
{
curveDefSelection.push_back( RiaSummaryCurveDefinition( ensemble, addr ) );
}
}
}
else
{
if ( !( sourceCase && sourceCase->summaryReader() ) ) continue;
const std::set<RifEclipseSummaryAddress>& readerAddresses = sourceCase->summaryReader()->allResultAddresses();
for ( const auto& addr : selectedAddressesFromUi )
{
if ( readerAddresses.count( addr ) )
{
curveDefSelection.push_back( RiaSummaryCurveDefinition( sourceCase, addr, false ) );
}
}
}
}
return curveDefSelection;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::setMultiSelectionMode( bool multiSelectionMode )
{
m_multiSelectionMode = multiSelectionMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::hideEnsembles( bool hide )
{
m_hideEnsembles = hide;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::hideSummaryCases( bool hide )
{
m_hideSummaryCases = hide;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::enableIndividualEnsembleCaseSelection( bool enable )
{
m_showIndividualEnsembleCases = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::hideDifferenceVectors( bool hide )
{
m_hideDifferenceVectors = hide;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::hideHistoryVectors( bool hide )
{
m_hideHistoryVectors = hide;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::hideVectorsWithoutHistory( bool hide )
{
m_hideVectorsWithoutHistory = hide;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::hideCalculationIncompatibleCategories( bool hide )
{
m_hideCalculationIncompatibleCategories = hide;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::setFieldChangedHandler( const std::function<void()>& handlerFunc )
{
m_toggleChangedHandler = handlerFunc;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::setDefaultSelection( const std::vector<SummarySource*>& defaultSources )
{
RimProject* proj = RimProject::current();
auto allSumCases = proj->allSummaryCases();
if ( !allSumCases.empty() )
{
RifEclipseSummaryAddress defaultAddress;
std::vector<SummarySource*> selectTheseSources = defaultSources;
if ( selectTheseSources.empty() ) selectTheseSources.push_back( allSumCases[0] );
std::vector<RiaSummaryCurveDefinition> curveDefs;
for ( SummarySource* s : selectTheseSources )
{
RimSummaryCase* sumCase = dynamic_cast<RimSummaryCase*>( s );
RimSummaryEnsemble* ensemble = dynamic_cast<RimSummaryEnsemble*>( s );
if ( ensemble )
{
curveDefs.push_back( RiaSummaryCurveDefinition( ensemble, defaultAddress ) );
}
else
{
curveDefs.push_back( RiaSummaryCurveDefinition( sumCase, defaultAddress, false ) );
}
}
setSelectedCurveDefinitions( curveDefs );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo>
RiuSummaryVectorSelectionUi::optionsForSummaryDataSource( bool hideSummaryCases, bool hideEnsembles, bool showIndividualEnsembleCases )
{
QList<caf::PdmOptionItemInfo> options;
RimProject* proj = RimProject::current();
std::vector<RimOilField*> oilFields = proj->allOilFields();
for ( RimOilField* oilField : oilFields )
{
RimSummaryCaseMainCollection* sumCaseMainColl = oilField->summaryCaseMainCollection();
if ( sumCaseMainColl )
{
if ( !hideSummaryCases )
{
// Top level cases
for ( const auto& sumCase : sumCaseMainColl->topLevelSummaryCases() )
{
options.push_back( caf::PdmOptionItemInfo( sumCase->displayCaseName(), sumCase ) );
}
}
// Ensembles
if ( !hideEnsembles )
{
bool ensembleHeaderCreated = false;
for ( const auto& ensemble : sumCaseMainColl->summaryEnsembles() )
{
if ( !ensemble->isEnsemble() ) continue;
if ( !ensembleHeaderCreated )
{
options.push_back( caf::PdmOptionItemInfo::createHeader( "Ensembles", true ) );
ensembleHeaderCreated = true;
}
// Ensemble level
{
auto optionItem = caf::PdmOptionItemInfo( ensemble->name(), ensemble );
optionItem.setLevel( 1 );
options.push_back( optionItem );
}
}
}
if ( !hideSummaryCases )
{
// Grouped cases
for ( const auto& ensemble : sumCaseMainColl->summaryEnsembles() )
{
if ( ensemble->isEnsemble() && !showIndividualEnsembleCases ) continue;
options.push_back( caf::PdmOptionItemInfo::createHeader( ensemble->name(), true ) );
for ( const auto& sumCase : ensemble->allSummaryCases() )
{
auto optionItem = caf::PdmOptionItemInfo( sumCase->displayCaseName(), sumCase );
optionItem.setLevel( 1 );
options.push_back( optionItem );
}
}
// Observed data
auto observedDataColl = oilField->observedDataCollection();
if ( !observedDataColl->allObservedSummaryData().empty() )
{
options.push_back( caf::PdmOptionItemInfo::createHeader( "Observed Data", true ) );
for ( const auto& obsData : observedDataColl->allObservedSummaryData() )
{
auto optionItem = caf::PdmOptionItemInfo( obsData->caseName(), obsData );
optionItem.setLevel( 1 );
options.push_back( optionItem );
}
}
}
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::setSelectedCurveDefinitions( const std::vector<RiaSummaryCurveDefinition>& curveDefinitions )
{
resetAllFields();
std::set<SummaryCategory> categories;
for ( const auto& curveDef : curveDefinitions )
{
if ( !( curveDef.summaryCaseY() || curveDef.isEnsembleCurve() ) ) continue;
RimSummaryCase* summaryCase = curveDef.summaryCaseY();
RifEclipseSummaryAddress summaryAddress = curveDef.summaryAddressY();
// Ignore ensemble statistics curves
if ( summaryAddress.isStatistics() ) continue;
// Select summary category if not already selected
auto& selectedCategories = m_selectedSummaryCategories();
if ( std::find( selectedCategories.begin(), selectedCategories.end(), summaryAddress.category() ) == selectedCategories.end() )
{
if ( summaryAddress.category() != SummaryCategory::SUMMARY_INVALID )
{
m_selectedSummaryCategories.v().push_back( summaryAddress.category() );
}
else
{
// Use field category as fall back category to avoid an empty list of vectors
summaryAddress = RifEclipseSummaryAddress::fieldAddress( "" );
}
}
// Select case if not already selected
if ( curveDef.isEnsembleCurve() )
{
if ( curveDef.ensemble() && !m_hideEnsembles )
{
if ( std::find( m_selectedSources.begin(), m_selectedSources.end(), curveDef.ensemble() ) == m_selectedSources.end() )
{
m_selectedSources.push_back( curveDef.ensemble() );
}
}
}
else
{
if ( curveDef.summaryCaseY() && ( !curveDef.ensemble() || m_showIndividualEnsembleCases ) )
{
if ( std::find( m_selectedSources.begin(), m_selectedSources.end(), curveDef.summaryCaseY() ) == m_selectedSources.end() )
{
m_selectedSources.push_back( curveDef.summaryCaseY() );
}
}
}
bool isObservedDataCase = isObservedData( summaryCase );
auto identifierAndFieldList = m_identifierFieldsMap[summaryAddress.category()];
for ( const auto& identifierAndField : identifierAndFieldList )
{
bool isVectorField = identifierAndField->summaryIdentifier() == SummaryIdentifierType::INPUT_VECTOR_NAME;
QString avalue = QString::fromStdString( summaryAddress.addressComponentUiText( identifierAndField->summaryIdentifier() ) );
if ( isVectorField && isObservedDataCase )
{
avalue = avalue + QString( OBSERVED_DATA_AVALUE_POSTFIX );
}
if ( isVectorField && summaryAddress.isCalculated() )
{
// Append calculation id to input vector name calculated data.
avalue = avalue + QString( ":%1" ).arg( summaryAddress.id() );
}
const auto& currentSelectionVector = identifierAndField->pdmField()->v();
if ( std::find( currentSelectionVector.begin(), currentSelectionVector.end(), avalue ) == currentSelectionVector.end() )
{
std::vector<QString> newSelectionVector( currentSelectionVector.begin(), currentSelectionVector.end() );
newSelectionVector.push_back( avalue );
( *identifierAndField->pdmField() ) = newSelectionVector;
}
}
categories.insert( curveDef.summaryAddressY().category() );
}
if ( !categories.empty() )
{
SummaryCategory cat = *( categories.begin() );
m_currentSummaryCategory.setValue( cat );
}
m_prevCurveCount = allCurveDefinitionsFromSelection().size();
m_prevCurveSetCount = allCurveSetDefinitionsFromSelections().size();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
if ( changedField != &m_selectedSources && changedField != &m_selectedSummaryCategories && changedField != &m_currentSummaryCategory )
{
SummaryCategory currentCategory = m_currentSummaryCategory();
if ( currentCategory != SummaryCategory::SUMMARY_INVALID )
{
// When a summary vector is selected, make sure the summary category for the summary vector is in the
// selection Note that we use the size of the variant to avoid this operation when an item in unchecked
if ( newValue.toList().size() > oldValue.toList().size() )
{
if ( std::find( m_selectedSummaryCategories.v().begin(), m_selectedSummaryCategories.v().end(), currentCategory ) ==
m_selectedSummaryCategories.v().end() )
{
m_selectedSummaryCategories.v().push_back( currentCategory );
}
}
if ( !newValue.toList().empty() )
{
auto identifierAndFieldList = m_identifierFieldsMap[currentCategory];
for ( const auto identifierAndField : identifierAndFieldList )
{
if ( identifierAndField->summaryIdentifier() == SummaryIdentifierType::INPUT_VECTOR_NAME ) continue;
auto v = identifierAndField->pdmField()->value();
if ( v.empty() )
{
auto field = identifierAndField->pdmField();
QList<caf::PdmOptionItemInfo> options;
appendOptionItemsForSubCategoriesAndVectors( options, identifierAndField );
if ( !options.isEmpty() )
{
std::vector<QString> values;
auto firstOption = options.front();
auto firstValue = firstOption.value();
QString valueText = firstValue.toString();
values.push_back( valueText );
field->setValue( values );
}
}
}
}
}
}
size_t curveCount = allCurveDefinitionsFromSelection().size();
size_t curveSetCount = allCurveSetDefinitionsFromSelections().size();
if ( m_toggleChangedHandler != nullptr )
{
// Do nothing if the curve count and curve set count is identical
if ( !m_multiSelectionMode || ( curveCount != m_prevCurveCount || curveSetCount != m_prevCurveSetCount ) )
{
m_toggleChangedHandler();
m_prevCurveCount = curveCount;
m_prevCurveSetCount = curveSetCount;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RiuSummaryVectorSelectionUi::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_selectedSources )
{
appendOptionItemsForSources( options );
}
else if ( fieldNeedingOptions == &m_selectedSummaryCategories )
{
appendOptionItemsForCategories( options );
}
else
{
// Lookup item type input field
auto identifierAndField = lookupIdentifierAndFieldFromFieldHandle( fieldNeedingOptions );
appendOptionItemsForSubCategoriesAndVectors( options, identifierAndField );
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
caf::PdmUiGroup* sourcesGroup = uiOrdering.addNewGroupWithKeyword( "Sources", RiuSummaryCurveDefinitionKeywords::sources() );
sourcesGroup->add( &m_selectedSources );
caf::PdmUiGroup* itemTypesGroup = uiOrdering.addNewGroupWithKeyword( "Summary Types", RiuSummaryCurveDefinitionKeywords::summaryTypes() );
itemTypesGroup->add( &m_selectedSummaryCategories );
caf::PdmField<std::vector<QString>>* summaryiesField = nullptr;
SummaryCategory sumCategory = m_currentSummaryCategory();
if ( sumCategory == SummaryCategory::SUMMARY_INVALID )
{
sumCategory = SummaryCategory::SUMMARY_FIELD;
}
if ( sumCategory == SummaryCategory::SUMMARY_FIELD )
{
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_FIELD][0]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_AQUIFER )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryAquifer() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_AQUIFER][0]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_AQUIFER][1]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_NETWORK )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryNetwork() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_NETWORK][0]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_NETWORK][1]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_MISC )
{
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_MISC][0]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_REGION )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryRegion() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION][0]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION][1]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_REGION_2_REGION )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( "Regions" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION_2_REGION][0]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_REGION_2_REGION][1]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_GROUP )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryWellGroup() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_GROUP][0]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_GROUP][1]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_WELL )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryWell() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL][0]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL][1]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_WELL_CONNECTION )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryWellConnection() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION][0]->pdmField() );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION][1]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION][2]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_WELL_CONNECTION_LGR )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryLgrConnection() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][0]->pdmField() );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][1]->pdmField() );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][2]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_CONNECTION_LGR][3]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_WELL_LGR )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryLgrWell() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_LGR][0]->pdmField() );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_LGR][1]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_LGR][2]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_WELL_SEGMENT )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryWellSegment() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_SEGMENT][0]->pdmField() );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_SEGMENT][1]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_SEGMENT][2]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_WELL_COMPLETION )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryWellCompletion() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_COMPLETION][0]->pdmField() );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_COMPLETION][1]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_WELL_COMPLETION][2]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_BLOCK )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryBlock() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK][0]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK][1]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_BLOCK_LGR )
{
{
caf::PdmUiGroup* myGroup = uiOrdering.addNewGroup( RiaDefines::summaryLgrBlock() + "s" );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK_LGR][0]->pdmField() );
myGroup->add( m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK_LGR][1]->pdmField() );
}
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_BLOCK_LGR][2]->pdmField();
}
else if ( sumCategory == SummaryCategory::SUMMARY_IMPORTED )
{
summaryiesField = m_identifierFieldsMap[SummaryCategory::SUMMARY_IMPORTED][0]->pdmField();
}
caf::PdmUiGroup* summariesGroup = uiOrdering.addNewGroupWithKeyword( "Summaries", RiuSummaryCurveDefinitionKeywords::summaries() );
if ( summaryiesField )
{
summariesGroup->add( summaryiesField );
}
uiOrdering.skipRemainingFields( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress>
RiuSummaryVectorSelectionUi::findPossibleSummaryAddressesFromSelectedCases( const SummaryIdentifierAndField* identifierAndField ) const
{
std::vector<SummarySource*> sources;
for ( const auto& source : m_selectedSources.value() )
{
RimSummaryCase* sumCase = dynamic_cast<RimSummaryCase*>( source.p() );
RimSummaryEnsemble* ensemble = dynamic_cast<RimSummaryEnsemble*>( source.p() );
if ( sumCase )
{
if ( !isObservedData( sumCase ) )
{
sources.push_back( sumCase );
}
}
else if ( ensemble )
{
sources.push_back( ensemble );
}
}
return findPossibleSummaryAddresses( sources, identifierAndField );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress>
RiuSummaryVectorSelectionUi::findPossibleSummaryAddressesFromSelectedObservedData( const SummaryIdentifierAndField* identifierAndField ) const
{
std::vector<SummarySource*> obsData;
for ( const auto& source : m_selectedSources.value() )
{
RimSummaryCase* sumCase = dynamic_cast<RimSummaryCase*>( source.p() );
if ( sumCase && isObservedData( sumCase ) )
{
obsData.push_back( sumCase );
}
}
return findPossibleSummaryAddresses( obsData, identifierAndField );
}
//--------------------------------------------------------------------------------------------------
/// Returns the summary addresses that match the selected item type and input selections made in GUI
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress>
RiuSummaryVectorSelectionUi::findPossibleSummaryAddresses( const std::vector<SummarySource*>& selectedSources,
const SummaryIdentifierAndField* identifierAndField ) const
{
std::set<RifEclipseSummaryAddress> addrUnion;
auto isVectorField = identifierAndField != nullptr && identifierAndField->summaryIdentifier() == SummaryIdentifierType::INPUT_VECTOR_NAME;
auto controllingIdentifierAndField = identifierAndField != nullptr ? lookupControllingField( identifierAndField ) : nullptr;
if ( !isVectorField && controllingIdentifierAndField != nullptr && controllingIdentifierAndField->pdmField()->v().empty() )
{
return addrUnion;
}
for ( SummarySource* currSource : selectedSources )
{
std::set<RifEclipseSummaryAddress> allAddresses;
RimSummaryCase* currCase = dynamic_cast<RimSummaryCase*>( currSource );
RimSummaryEnsemble* currEnsemble = dynamic_cast<RimSummaryEnsemble*>( currSource );
if ( currCase )
{
if ( RifSummaryReaderInterface* reader = currCase->summaryReader() )
{
reader->createAddressesIfRequired();
allAddresses = reader->allResultAddresses();
}
}
else if ( currEnsemble )
{
allAddresses = currEnsemble->ensembleSummaryAddresses();
}
bool applySelections = identifierAndField == nullptr || ( !isVectorField && controllingIdentifierAndField != nullptr );
std::vector<SummaryIdentifierAndField*> controllingFields;
if ( applySelections )
{
// Build selections vector
controllingFields = buildControllingFieldList( identifierAndField );
}
for ( auto& address : allAddresses )
{
if ( address.category() == m_currentSummaryCategory() )
{
bool addressSelected = applySelections ? isAddressCompatibleWithControllingFieldSelection( address, controllingFields ) : true;
if ( addressSelected )
{
addrUnion.insert( address );
}
}
}
}
if ( m_hideHistoryVectors || m_hideDifferenceVectors )
{
std::set<RifEclipseSummaryAddress> filteredAddresses;
for ( const auto& adr : addrUnion )
{
if ( m_hideHistoryVectors && adr.isHistoryVector() ) continue;
if ( m_hideDifferenceVectors )
{
const auto diffText = RifEclipseSummaryAddressDefines::differenceIdentifier();
if ( RiaStdStringTools::endsWith( adr.vectorName(), diffText ) ) continue;
}
if ( m_hideVectorsWithoutHistory )
{
auto candidateName = adr.vectorName() + RifEclipseSummaryAddressDefines::historyIdentifier();
bool found = false;
for ( const auto& ad : addrUnion )
{
if ( ad.vectorName() == candidateName ) found = true;
}
if ( !found ) continue;
}
filteredAddresses.insert( adr );
}
addrUnion.swap( filteredAddresses );
}
return addrUnion;
}
//--------------------------------------------------------------------------------------------------
/// Build a list of relevant selections
//--------------------------------------------------------------------------------------------------
std::vector<SummaryIdentifierAndField*>
RiuSummaryVectorSelectionUi::buildControllingFieldList( const SummaryIdentifierAndField* identifierAndField ) const
{
std::vector<SummaryIdentifierAndField*> controllingFields;
const auto& identifierAndFieldList = m_identifierFieldsMap.at( m_currentSummaryCategory() );
for ( const auto& identifierAndFieldItem : identifierAndFieldList )
{
if ( identifierAndFieldItem == identifierAndField )
{
break;
}
controllingFields.push_back( identifierAndFieldItem );
}
return controllingFields;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
SummaryIdentifierAndField* RiuSummaryVectorSelectionUi::lookupIdentifierAndFieldFromFieldHandle( const caf::PdmFieldHandle* pdmFieldHandle ) const
{
for ( const auto& itemTypes : m_identifierFieldsMap )
{
for ( const auto& itemTypeInput : itemTypes.second )
{
if ( pdmFieldHandle == itemTypeInput->pdmField() )
{
return itemTypeInput;
}
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
/// Returns the Controlling pdm field info for the specified pdm field info.
/// Controlling means the field controlling the dependent field
/// If the specified pdm field info is the topmost (i.e. index is 0), nullptr is returned
//--------------------------------------------------------------------------------------------------
SummaryIdentifierAndField* RiuSummaryVectorSelectionUi::lookupControllingField( const SummaryIdentifierAndField* dependentField ) const
{
for ( const auto& identifierAndFieldList : m_identifierFieldsMap )
{
int index = 0;
for ( const auto& iaf : identifierAndFieldList.second )
{
if ( iaf == dependentField )
{
return index > 0 ? identifierAndFieldList.second[index - 1] : nullptr;
}
index++;
}
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuSummaryVectorSelectionUi::isAddressCompatibleWithControllingFieldSelection(
const RifEclipseSummaryAddress& address,
const std::vector<SummaryIdentifierAndField*>& identifierAndFieldList ) const
{
for ( const auto& identifierAndField : identifierAndFieldList )
{
bool match = false;
for ( const auto& selectedText : identifierAndField->pdmField()->v() )
{
if ( QString::compare( QString::fromStdString( address.addressComponentUiText( identifierAndField->summaryIdentifier() ) ),
selectedText ) == 0 )
{
match = true;
break;
}
}
if ( !match )
{
return false;
}
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress> RiuSummaryVectorSelectionUi::buildAddressListFromSelections() const
{
std::set<RifEclipseSummaryAddress> addressSet;
for ( const auto& category : m_selectedSummaryCategories() )
{
if ( m_identifierFieldsMap.at( category ).empty() || category == SummaryCategory::SUMMARY_INVALID ) continue;
const auto& identifierAndFieldList = m_identifierFieldsMap.at( category );
std::vector<std::pair<SummaryIdentifierType, QString>> selectionStack;
buildAddressListForCategoryRecursively( category, identifierAndFieldList.begin(), selectionStack, addressSet );
}
return addressSet;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::buildAddressListForCategoryRecursively(
SummaryCategory category,
std::vector<SummaryIdentifierAndField*>::const_iterator identifierAndFieldItr,
std::vector<std::pair<SummaryIdentifierType, QString>>& identifierPath,
std::set<RifEclipseSummaryAddress>& addressSet ) const
{
for ( const auto& identifierText : ( *identifierAndFieldItr )->pdmField()->v() )
{
auto idText = identifierText;
// Calculated results have a id appended. E.g. "Calculation_3 ( NORNE_ATW2013, WOPR:B-4H ):3"
if ( ( *identifierAndFieldItr )->summaryIdentifier() == SummaryIdentifierType::INPUT_VECTOR_NAME )
{
// Extract the calculation id
QStringList tokens = idText.split( ":" );
if ( tokens.size() > 1 )
{
QString calculationId = tokens.last();
// Put the input vector name back together
tokens.pop_back();
idText = tokens.join( ":" );
identifierPath.push_back( std::make_pair( SummaryIdentifierType::INPUT_ID, calculationId ) );
}
}
idText.remove( OBSERVED_DATA_AVALUE_POSTFIX );
identifierPath.push_back( std::make_pair( ( *identifierAndFieldItr )->summaryIdentifier(), idText ) );
if ( ( *identifierAndFieldItr )->summaryIdentifier() != SummaryIdentifierType::INPUT_VECTOR_NAME )
{
buildAddressListForCategoryRecursively( category, std::next( identifierAndFieldItr, 1 ), identifierPath, addressSet );
}
else
{
std::map<SummaryIdentifierType, std::string> selectedIdentifiers;
for ( const auto& identifier : identifierPath )
{
selectedIdentifiers.insert( std::make_pair( identifier.first, identifier.second.toStdString() ) );
}
auto address = RifEclipseSummaryAddress( category, selectedIdentifiers );
addressSet.insert( address );
}
if ( !identifierPath.empty() )
{
identifierPath.pop_back();
if ( !identifierPath.empty() && identifierPath.back().first == SummaryIdentifierType::INPUT_ID )
{
// If the last identifier is an id, remove it as we get two ids for calculated results. One entry for the input vector name
// and one for the calculation id
identifierPath.pop_back();
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::defineEditorAttribute( const caf::PdmFieldHandle* field,
QString uiConfigName,
caf::PdmUiEditorAttribute* attribute )
{
caf::PdmUiTreeSelectionEditorAttribute* attrib = dynamic_cast<caf::PdmUiTreeSelectionEditorAttribute*>( attribute );
if ( attrib )
{
if ( &m_selectedSummaryCategories == field )
{
attrib->currentIndexFieldHandle = &m_currentSummaryCategory;
attrib->showTextFilter = false;
attrib->showToggleAllCheckbox = false;
}
// All tree selection editors are set in specified selection mode
attrib->singleSelectionMode = !m_multiSelectionMode;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::resetAllFields()
{
m_selectedSources.clearWithoutDelete();
m_selectedSummaryCategories = std::vector<caf::AppEnum<SummaryCategory>>();
// clear all state in fields
for ( auto& identifierAndFieldList : m_identifierFieldsMap )
{
for ( auto a : identifierAndFieldList.second )
{
a->pdmField()->v().clear();
}
}
m_prevCurveCount = 0;
m_prevCurveSetCount = 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiuSummaryVectorSelectionUi::isObservedData( const RimSummaryCase* sumCase ) const
{
return dynamic_cast<const RimObservedSummaryData*>( sumCase ) != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<SummarySource*> RiuSummaryVectorSelectionUi::selectedSummarySources() const
{
std::vector<SummarySource*> sources;
for ( const auto& source : m_selectedSources )
{
sources.push_back( source );
}
return sources;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::appendOptionItemsForSources( QList<caf::PdmOptionItemInfo>& options ) const
{
auto dataSourceOptions = optionsForSummaryDataSource( m_hideSummaryCases, m_hideEnsembles, m_showIndividualEnsembleCases );
for ( auto& o : dataSourceOptions )
{
options.push_back( o );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::appendOptionItemsForCategories( QList<caf::PdmOptionItemInfo>& options ) const
{
std::vector<SummaryCategory> sortedCategoriesForUi;
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_FIELD );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_AQUIFER );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_NETWORK );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_MISC );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_REGION );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_REGION_2_REGION );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_GROUP );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_WELL );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_WELL_COMPLETION );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_WELL_CONNECTION );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_BLOCK );
if ( !m_hideCalculationIncompatibleCategories )
{
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_WELL_SEGMENT );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_WELL_LGR );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_WELL_CONNECTION_LGR );
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_BLOCK_LGR );
}
sortedCategoriesForUi.push_back( SummaryCategory::SUMMARY_IMPORTED );
for ( auto category : sortedCategoriesForUi )
{
auto option = RiaOptionItemFactory::optionItemFromSummaryType( category );
options.push_back( option );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuSummaryVectorSelectionUi::appendOptionItemsForSubCategoriesAndVectors( QList<caf::PdmOptionItemInfo>& options,
SummaryIdentifierAndField* identifierAndField ) const
{
if ( identifierAndField == nullptr ) return;
enum
{
SUM_CASES,
OBS_DATA,
};
const int itemCount = OBS_DATA + 1;
std::set<RifEclipseSummaryAddress> addrUnion[itemCount];
addrUnion[SUM_CASES] = findPossibleSummaryAddressesFromSelectedCases( identifierAndField );
addrUnion[OBS_DATA] = findPossibleSummaryAddressesFromSelectedObservedData( identifierAndField );
bool isVectorField = identifierAndField->summaryIdentifier() == SummaryIdentifierType::INPUT_VECTOR_NAME;
std::set<std::string> itemNames[itemCount];
for ( int i = 0; i < itemCount; i++ )
{
for ( const auto& address : addrUnion[i] )
{
if ( address.isErrorResult() ) continue;
auto name = address.addressComponentUiText( identifierAndField->summaryIdentifier() );
if ( !name.empty() )
{
if ( isVectorField && address.isCalculated() )
{
name += QString( ":%1" ).arg( address.id() ).toStdString();
}
itemNames[i].insert( name );
}
}
}
// Merge sets for all other fields than vector fields
if ( !isVectorField )
{
itemNames[SUM_CASES].insert( itemNames[OBS_DATA].begin(), itemNames[OBS_DATA].end() );
itemNames[OBS_DATA].clear();
}
for ( int i = 0; i < itemCount; i++ )
{
// Create headers only for vector fields when observed data is selected
bool hasObservedData = !itemNames[OBS_DATA].empty();
bool groupItems = isVectorField && hasObservedData;
if ( groupItems )
{
QString headerText;
if ( i == SUM_CASES )
{
headerText = QString( "Simulated Data" );
}
else if ( i == OBS_DATA )
{
headerText = QString( "Observed Data" );
}
if ( !headerText.isEmpty() )
{
options.push_back( caf::PdmOptionItemInfo::createHeader( headerText, true ) );
}
}
auto itemPostfix = ( isVectorField && i == OBS_DATA ) ? QString( OBSERVED_DATA_AVALUE_POSTFIX ) : QString( "" );
// Sort numeric identifiers by numeric val
std::vector<std::string> itemNamesVector;
{
switch ( identifierAndField->summaryIdentifier() )
{
case SummaryIdentifierType::INPUT_REGION_NUMBER:
case SummaryIdentifierType::INPUT_SEGMENT_NUMBER:
case SummaryIdentifierType::INPUT_WELL_COMPLETION_NUMBER:
case SummaryIdentifierType::INPUT_AQUIFER_NUMBER:
{
std::set<int> values;
for ( const std::string& itemName : itemNames[i] )
{
values.insert( RiaStdStringTools::toInt( itemName ) );
}
for ( int v : values )
{
itemNamesVector.push_back( std::to_string( v ) );
}
break;
}
default:
itemNamesVector.insert( itemNamesVector.end(), itemNames[i].begin(), itemNames[i].end() );
break;
}
}
for ( const auto& itemName : itemNamesVector )
{
QString displayName;
if ( isVectorField )
{
std::string longVectorName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( itemName );
if ( longVectorName.empty() )
{
displayName = QString::fromStdString( itemName );
}
else
{
displayName = QString::fromStdString( longVectorName );
displayName += QString( " (%1)" ).arg( QString::fromStdString( itemName ) );
}
}
else
{
displayName = QString::fromStdString( itemName );
}
auto optionItem = caf::PdmOptionItemInfo( displayName, QString::fromStdString( itemName ) + itemPostfix );
if ( groupItems ) optionItem.setLevel( 1 );
options.push_back( optionItem );
}
}
}