diff --git a/ApplicationLibCode/Commands/PlotBuilderCommands/RicSplitMultiPlotFeature.cpp b/ApplicationLibCode/Commands/PlotBuilderCommands/RicSplitMultiPlotFeature.cpp index 31d821f5d8..e00ec82a79 100644 --- a/ApplicationLibCode/Commands/PlotBuilderCommands/RicSplitMultiPlotFeature.cpp +++ b/ApplicationLibCode/Commands/PlotBuilderCommands/RicSplitMultiPlotFeature.cpp @@ -68,7 +68,7 @@ void RicSplitMultiPlotFeature::onActionTriggered( bool isChecked ) for ( auto curveSet : plot->curveSets() ) { - RimSummaryAddress* addr = RimSummaryAddress::wrapFileReaderAddress( curveSet->summaryAddress() ); + RimSummaryAddress* addr = RimSummaryAddress::wrapFileReaderAddress( curveSet->summaryAddressY() ); addr->setEnsembleId( curveSet->ensembleId() ); objects.push_back( addr ); } diff --git a/ApplicationLibCode/Commands/PlotBuilderCommands/RicSummaryPlotBuilder.cpp b/ApplicationLibCode/Commands/PlotBuilderCommands/RicSummaryPlotBuilder.cpp index 22192b7607..9881a6ffa5 100644 --- a/ApplicationLibCode/Commands/PlotBuilderCommands/RicSummaryPlotBuilder.cpp +++ b/ApplicationLibCode/Commands/PlotBuilderCommands/RicSummaryPlotBuilder.cpp @@ -250,7 +250,7 @@ RimEnsembleCurveSet* RicSummaryPlotBuilder::createCurveSet( RimSummaryCaseCollec auto curveSet = new RimEnsembleCurveSet(); curveSet->setSummaryCaseCollection( ensemble ); - curveSet->setSummaryAddressAndStatisticsFlag( addr ); + curveSet->setSummaryAddressYAndStatisticsFlag( addr ); return curveSet; } diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSaveMultiPlotTemplateFeature.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSaveMultiPlotTemplateFeature.cpp index b354fcafce..a44c3cf7d2 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSaveMultiPlotTemplateFeature.cpp +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSaveMultiPlotTemplateFeature.cpp @@ -218,7 +218,7 @@ QString RicSaveMultiPlotTemplateFeature::createTextFromObject( RimSummaryMultiPl ensembleReferenceStrings.insert( reference ); } - addresses.push_back( curveSet->summaryAddress() ); + addresses.push_back( curveSet->summaryAddressY() ); } replaceStrings( ensembleReferenceStrings, diff --git a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp index d1e042442a..0717d016d0 100644 --- a/ApplicationLibCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp +++ b/ApplicationLibCode/Commands/PlotTemplateCommands/RicSummaryPlotTemplateTools.cpp @@ -320,11 +320,16 @@ void RicSummaryPlotTemplateTools::setValuesForPlaceholders( RimSummaryPlot* } // Replace placeholders with object names from selection - auto curveAdr = curveSet->summaryAddress(); - setPlaceholderWellName( &curveAdr, wellNames ); - setPlaceholderGroupName( &curveAdr, groupNames ); - setPlaceholderRegion( &curveAdr, regions ); - curveSet->setSummaryAddressAndStatisticsFlag( curveAdr ); + auto adr = curveSet->curveAddress(); + auto curveAdrY = adr.summaryAddressY(); + setPlaceholderWellName( &curveAdrY, wellNames ); + setPlaceholderGroupName( &curveAdrY, groupNames ); + setPlaceholderRegion( &curveAdrY, regions ); + auto curveAdrX = adr.summaryAddressX(); + setPlaceholderWellName( &curveAdrX, wellNames ); + setPlaceholderGroupName( &curveAdrX, groupNames ); + setPlaceholderRegion( &curveAdrX, regions ); + curveSet->setCurveAddress( RiaSummaryCurveAddress( curveAdrX, curveAdrY ) ); } } } diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.cpp index b70e8c06d7..baba91dfb7 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewEnsembleCurveFilterFeature.cpp @@ -61,7 +61,7 @@ void RicNewEnsembleCurveFilterFeature::onActionTriggered( bool isChecked ) { std::vector addresses; - auto candidateAdr = newFilter->parentCurveSet()->summaryAddress(); + auto candidateAdr = newFilter->parentCurveSet()->summaryAddressY(); auto nativeQuantityName = RimObjectiveFunctionTools::nativeQuantityName( candidateAdr.vectorName() ); candidateAdr.setVectorName( nativeQuantityName ); addresses.push_back( candidateAdr ); diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp index 0b066840fe..3de987c369 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicNewSummaryEnsembleCurveSetFeature.cpp @@ -89,7 +89,7 @@ std::vector RicNewSummaryEnsembleCurveSetFeature::addDefau RimEnsembleCurveSetColorManager::cycledEnsembleColorRange( static_cast( colorIndex ) ) ) ); curveSet->setSummaryCaseCollection( ensemble ); - curveSet->setSummaryAddressAndStatisticsFlag( addr ); + curveSet->setSummaryAddressYAndStatisticsFlag( addr ); auto filter = curveSet->filterCollection()->addFilter(); filter->setActive( false ); diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotEditorUi.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotEditorUi.cpp index a5ee881a28..82dc74aaed 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotEditorUi.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotEditorUi.cpp @@ -412,7 +412,7 @@ void RicSummaryPlotEditorUi::syncPreviewCurvesFromUiSelection() for ( const auto& curveSet : currentCurveSetsInPreviewPlot ) { RimSummaryCaseCollection* ensemble = curveSet->summaryCaseCollection(); - currentCurveSetDefs.insert( RiaCurveSetDefinition( ensemble, curveSet->summaryAddress() ) ); + currentCurveSetDefs.insert( RiaCurveSetDefinition( ensemble, curveSet->summaryAddressY() ) ); } if ( allCurveSetDefinitions.size() < currentCurveSetsInPreviewPlot.size() ) @@ -428,7 +428,7 @@ void RicSummaryPlotEditorUi::syncPreviewCurvesFromUiSelection() for ( const auto& curveSet : currentCurveSetsInPreviewPlot ) { RimSummaryCaseCollection* ensemble = curveSet->summaryCaseCollection(); - RiaCurveSetDefinition curveSetDef = RiaCurveSetDefinition( ensemble, curveSet->summaryAddress() ); + RiaCurveSetDefinition curveSetDef = RiaCurveSetDefinition( ensemble, curveSet->summaryAddressY() ); if ( deleteCurveSetDefs.count( curveSetDef ) > 0 ) curveSetsToDelete.insert( curveSet ); } } @@ -489,7 +489,7 @@ void RicSummaryPlotEditorUi::updatePreviewCurvesFromCurveDefinitions( const std: RimEnsembleCurveSet* curveSet = nullptr; for ( const auto& cs : m_previewPlot->ensembleCurveSetCollection()->curveSets() ) { - if ( cs->summaryCaseCollection() == curveDef.ensemble() && cs->summaryAddress() == curveDef.summaryAddressY() ) + if ( cs->summaryCaseCollection() == curveDef.ensemble() && cs->summaryAddressY() == curveDef.summaryAddressY() ) { curveSet = cs; break; @@ -503,7 +503,7 @@ void RicSummaryPlotEditorUi::updatePreviewCurvesFromCurveDefinitions( const std: // Do not call setSummaryAddressAndStatisticsFlag() here, as the call to m_statistics->updateAllRequiredEditors(); causes a // crash in updateUiOrdering. The statistics curves will be created when the curve set is added to the plot. - curveSet->setSummaryAddress( curveDef.summaryAddressY() ); + curveSet->setSummaryAddressY( curveDef.summaryAddressY() ); // Set single curve set color auto allCurveSets = m_previewPlot->ensembleCurveSetCollection()->curveSets(); @@ -644,7 +644,7 @@ void RicSummaryPlotEditorUi::populateCurveCreator( const RimSummaryPlot& sourceS previewCurveSetColl->addCurveSet( newCurveSet ); RimSummaryCaseCollection* ensemble = curveSet->summaryCaseCollection(); - curveDefs.emplace_back( ensemble, curveSet->summaryAddress() ); + curveDefs.emplace_back( ensemble, curveSet->summaryAddressY() ); } m_previewPlot->copyAxisPropertiesFromOther( sourceSummaryPlot ); @@ -958,12 +958,12 @@ void RicSummaryPlotEditorUi::setInitialCurveVisibility( const RimSummaryPlot* ta std::set> sourceCurveSetDefs; for ( const auto& curveSet : targetPlot->ensembleCurveSetCollection()->curveSets() ) { - sourceCurveSetDefs.insert( std::make_pair( curveSet->summaryCaseCollection(), curveSet->summaryAddress() ) ); + sourceCurveSetDefs.insert( std::make_pair( curveSet->summaryCaseCollection(), curveSet->summaryAddressY() ) ); } for ( const auto& curveSet : m_previewPlot->ensembleCurveSetCollection()->curveSets() ) { - auto curveDef = std::make_pair( curveSet->summaryCaseCollection(), curveSet->summaryAddress() ); + auto curveDef = std::make_pair( curveSet->summaryCaseCollection(), curveSet->summaryAddressY() ); if ( sourceCurveSetDefs.count( curveDef ) == 0 ) { curveSet->showCurves( false ); diff --git a/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp b/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp index 7658cbdb1a..00d3b50c08 100644 --- a/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp +++ b/ApplicationLibCode/Commands/SummaryPlotCommands/RicSummaryPlotFeatureImpl.cpp @@ -553,7 +553,7 @@ RimEnsembleCurveSet* RicSummaryPlotFeatureImpl::createCurveSet( RimSummaryCaseCo auto curveSet = new RimEnsembleCurveSet(); curveSet->setSummaryCaseCollection( ensemble ); - curveSet->setSummaryAddressAndStatisticsFlag( addr ); + curveSet->setSummaryAddressYAndStatisticsFlag( addr ); if ( ensembleColoringStyle == EnsembleColoringType::PARAMETER || ensembleColoringStyle == EnsembleColoringType::LOG_PARAMETER ) { diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCrossPlotStatisticsCase.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCrossPlotStatisticsCase.cpp index 53bb13ed3f..7afe579324 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCrossPlotStatisticsCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCrossPlotStatisticsCase.cpp @@ -31,13 +31,6 @@ #include #include -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEnsembleCrossPlotStatisticsCase::RimEnsembleCrossPlotStatisticsCase() -{ -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -113,7 +106,7 @@ void RimEnsembleCrossPlotStatisticsCase::calculate( const std::vector> pairs; + struct SampleData + { + double xValue; + double yValue; + int realizationId; + }; + + std::vector sampleData; auto [minTimeStep, maxTimeStep] = RimEnsembleStatisticsCase::findMinMaxTimeStep( sumCases, inputAddressX ); RiaDefines::DateTimePeriod period = RimEnsembleStatisticsCase::findBestResamplingPeriod( minTimeStep, maxTimeStep ); for ( const auto& sumCase : sumCases ) { + int realizationId = sumCase->caseId(); + const auto& reader = sumCase->summaryReader(); if ( reader ) { @@ -155,52 +157,72 @@ void RimEnsembleCrossPlotStatisticsCase::calculate( const std::vectorfirst; - auto maxX = p.second->first; - auto rangeX = maxX - minX; - auto deltaRangeX = rangeX / binCount; + // Sort on X values + std::sort( sampleData.begin(), sampleData.end(), []( const auto& lhs, const auto& rhs ) { return lhs.xValue < rhs.xValue; } ); + + auto minX = sampleData.front().xValue; + auto maxX = sampleData.back().xValue; + auto rangeX = maxX - minX; + auto deltaRangeX = rangeX / binCount; double currentX = minX; - std::vector binnedYValues; - for ( auto v : pairs ) + std::map> yValuesPerRealization; + for ( auto v : sampleData ) { - if ( v.first < currentX + deltaRangeX ) + if ( v.xValue < currentX + deltaRangeX ) { - binnedYValues.emplace_back( v.second ); + yValuesPerRealization[v.realizationId].emplace_back( v.yValue ); } else { // Add statistics for current bin if sample count is above threshold - // TODO: Add option to skip bin if unique realization count is below threshold - - if ( static_cast( binnedYValues.size() ) > sampleCountThreshold ) + if ( static_cast( yValuesPerRealization.size() ) > realizationCountThreshold ) { + std::vector meanYPerRealization; + + for ( const auto& [id, values] : yValuesPerRealization ) + { + if ( values.empty() ) continue; + + double sum = 0.0; + for ( double value : values ) + { + sum += value; + } + + meanYPerRealization.emplace_back( sum / values.size() ); + } + double p10, p50, p90, mean; - RigStatisticsMath::calculateStatisticsCurves( binnedYValues, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED ); + RigStatisticsMath::calculateStatisticsCurves( meanYPerRealization, + &p10, + &p50, + &p90, + &mean, + RigStatisticsMath::PercentileStyle::SWITCHED ); m_p10Data.push_back( p10 ); m_p50Data.push_back( p50 ); m_p90Data.push_back( p90 ); m_meanData.push_back( mean ); - m_binnedXValues.emplace_back( currentX ); + // Use middle of bin as X value + m_binnedXValues.emplace_back( currentX + deltaRangeX / 2.0 ); } currentX += deltaRangeX; - binnedYValues.clear(); + yValuesPerRealization.clear(); } } } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCrossPlotStatisticsCase.h b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCrossPlotStatisticsCase.h index e3ced3bbd4..478790c229 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCrossPlotStatisticsCase.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCrossPlotStatisticsCase.h @@ -33,14 +33,12 @@ class RifEclipseSummaryAddress; class RimEnsembleCrossPlotStatisticsCase : public RimSummaryCase, public RifSummaryReaderInterface { public: - RimEnsembleCrossPlotStatisticsCase(); - void calculate( const std::vector& sumCases, const RifEclipseSummaryAddress& inputAddressX, const RifEclipseSummaryAddress& inputAddressY, bool includeIncompleteCurves, int binCount, - int sampleCountThreshold ); + int realizationCountThreshold ); bool hasP10Data() const; bool hasP50Data() const; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.cpp index 1597a6700c..179b3d1fd7 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveFilter.cpp @@ -350,7 +350,7 @@ void RimEnsembleCurveFilter::fieldChangedByUi( const caf::PdmFieldHandle* change { RimSummaryAddress* summaryAddress = new RimSummaryAddress(); - RifEclipseSummaryAddress candidateAdr = parentCurveSet()->summaryAddress(); + RifEclipseSummaryAddress candidateAdr = parentCurveSet()->summaryAddressY(); auto nativeQuantityName = RimObjectiveFunctionTools::nativeQuantityName( candidateAdr.vectorName() ); candidateAdr.setVectorName( nativeQuantityName ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp index 6d1c9274ab..4cba269f42 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp @@ -410,7 +410,7 @@ void RimEnsembleCurveSet::deleteCurve( RimSummaryCurve* curve ) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEnsembleCurveSet::setSummaryAddress( RifEclipseSummaryAddress address ) +void RimEnsembleCurveSet::setSummaryAddressY( RifEclipseSummaryAddress address ) { m_yValuesSummaryAddress->setAddress( address ); RimSummaryAddress* summaryAddress = new RimSummaryAddress(); @@ -423,7 +423,7 @@ void RimEnsembleCurveSet::setSummaryAddress( RifEclipseSummaryAddress address ) //-------------------------------------------------------------------------------------------------- void RimEnsembleCurveSet::setCurveAddress( RiaSummaryCurveAddress address ) { - setSummaryAddress( address.summaryAddressY() ); + setSummaryAddressY( address.summaryAddressY() ); setSummaryAddressX( address.summaryAddressX() ); if ( address.summaryAddressX().category() == SummaryCategory::SUMMARY_TIME ) @@ -455,9 +455,9 @@ bool RimEnsembleCurveSet::isXAxisSummaryVector() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimEnsembleCurveSet::setSummaryAddressAndStatisticsFlag( RifEclipseSummaryAddress address ) +void RimEnsembleCurveSet::setSummaryAddressYAndStatisticsFlag( RifEclipseSummaryAddress address ) { - setSummaryAddress( address ); + setSummaryAddressY( address ); m_statistics->setShowStatisticsCurves( !address.isHistoryVector() ); m_statistics->updateAllRequiredEditors(); } @@ -465,7 +465,7 @@ void RimEnsembleCurveSet::setSummaryAddressAndStatisticsFlag( RifEclipseSummaryA //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RifEclipseSummaryAddress RimEnsembleCurveSet::summaryAddress() const +RifEclipseSummaryAddress RimEnsembleCurveSet::summaryAddressY() const { return m_yValuesSummaryAddress->address(); } @@ -477,10 +477,10 @@ RiaSummaryCurveAddress RimEnsembleCurveSet::curveAddress() const { if ( m_xAxisType() == RiaDefines::HorizontalAxisType::TIME ) { - return RiaSummaryCurveAddress( RifEclipseSummaryAddress::timeAddress(), summaryAddress() ); + return RiaSummaryCurveAddress( RifEclipseSummaryAddress::timeAddress(), summaryAddressY() ); } - return RiaSummaryCurveAddress( m_xAddressSelector->summaryAddress(), summaryAddress() ); + return RiaSummaryCurveAddress( m_xAddressSelector->summaryAddress(), summaryAddressY() ); } //-------------------------------------------------------------------------------------------------- @@ -742,7 +742,7 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi if ( !m_xAddressSelector->ensemble() ) { m_xAddressSelector->setEnsemble( summaryCaseCollection() ); - m_xAddressSelector->setAddress( summaryAddress() ); + m_xAddressSelector->setAddress( summaryAddressY() ); } if ( !m_xAddressSelector->plotAxisProperties() ) @@ -2015,14 +2015,14 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vectorcalculate( statCases, m_xAddressSelector->summaryAddress(), - summaryAddress(), + summaryAddressY(), m_statistics->includeIncompleteCurves(), m_statistics->crossPlotCurvesBinCount(), - m_statistics->crossPlotCurvesSampleCountThresholdPerBin() ); + m_statistics->crossPlotRealizationCountThresholdPerBin() ); } else { - m_ensembleStatCaseY->calculate( statCases, summaryAddress(), m_statistics->includeIncompleteCurves() ); + m_ensembleStatCaseY->calculate( statCases, summaryAddressY(), m_statistics->includeIncompleteCurves() ); } } @@ -2203,12 +2203,12 @@ std::vector> RimEnsembleCurveSet::ensemb { if ( sortingMode == ParameterSorting::ABSOLUTE_VALUE ) { - return ensemble->correlationSortedEnsembleParameters( summaryAddress() ); + return ensemble->correlationSortedEnsembleParameters( summaryAddressY() ); } if ( sortingMode == ParameterSorting::ALPHABETICALLY ) { - auto parameters = ensemble->parameterCorrelationsAllTimeSteps( summaryAddress() ); + auto parameters = ensemble->parameterCorrelationsAllTimeSteps( summaryAddressY() ); std::sort( parameters.begin(), parameters.end(), []( const auto& lhs, const auto& rhs ) { return lhs.first.name < rhs.first.name; } ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h index b8899977d8..f8793601ef 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.h @@ -113,10 +113,10 @@ public: void addCurve( RimSummaryCurve* curve ); void deleteCurve( RimSummaryCurve* curve ); - void setSummaryAddress( RifEclipseSummaryAddress address ); + void setSummaryAddressY( RifEclipseSummaryAddress address ); void setCurveAddress( RiaSummaryCurveAddress address ); - void setSummaryAddressAndStatisticsFlag( RifEclipseSummaryAddress address ); - RifEclipseSummaryAddress summaryAddress() const; + void setSummaryAddressYAndStatisticsFlag( RifEclipseSummaryAddress address ); + RifEclipseSummaryAddress summaryAddressY() const; RiaSummaryCurveAddress curveAddress() const; std::vector curves() const; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.cpp index f5abf9b7fd..d473b16362 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSetCollection.cpp @@ -262,10 +262,10 @@ std::vector RimEnsembleCurveSetCollection::curveSetsForSou { // Add corresponding history/summary curve with or without H - std::string vectorName = m_curveSetForSourceStepping->summaryAddress().vectorName(); + std::string vectorName = m_curveSetForSourceStepping->summaryAddressY().vectorName(); std::string candidateName; - if ( m_curveSetForSourceStepping->summaryAddress().isHistoryVector() ) + if ( m_curveSetForSourceStepping->summaryAddressY().isHistoryVector() ) { candidateName = vectorName.substr( 0, vectorName.size() - 1 ); } @@ -276,7 +276,7 @@ std::vector RimEnsembleCurveSetCollection::curveSetsForSou for ( const auto& c : curveSets() ) { - if ( c->summaryAddress().vectorName() == candidateName ) + if ( c->summaryAddressY().vectorName() == candidateName ) { steppingCurveSets.push_back( c ); } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatistics.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatistics.cpp index 79a9715281..6153f456fd 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatistics.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatistics.cpp @@ -47,10 +47,10 @@ RimEnsembleStatistics::RimEnsembleStatistics( RimEnsembleCurveSetInterface* pare CAF_PDM_InitField( &m_includeIncompleteCurves, "IncludeIncompleteCurves", false, "Include Incomplete Curves" ); CAF_PDM_InitField( &m_crossPlotCurvesBinCount, "CrossPlotCurvesBinCount", 100, "Bin Count" ); - CAF_PDM_InitField( &m_crossPlotCurvesStatisticsSampleCountThresholdPerBin, - "CrossPlotCurvesStatisticsSampleCountThresholdPerBin", - 100, - "Sample Threshold per Bin" ); + CAF_PDM_InitField( &m_crossPlotCurvesStatisticsRealizationCountThresholdPerBin, + "CrossPlotCurvesStatisticsRealizationCountThresholdPerBin", + 10, + "Realization Count Threshold per Bin" ); CAF_PDM_InitField( &m_warningLabel, "WarningLabel", QString( "Warning: Ensemble time range mismatch" ), "" ); @@ -96,9 +96,9 @@ int RimEnsembleStatistics::crossPlotCurvesBinCount() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int RimEnsembleStatistics::crossPlotCurvesSampleCountThresholdPerBin() const +int RimEnsembleStatistics::crossPlotRealizationCountThresholdPerBin() const { - return m_crossPlotCurvesStatisticsSampleCountThresholdPerBin; + return m_crossPlotCurvesStatisticsRealizationCountThresholdPerBin; } //-------------------------------------------------------------------------------------------------- @@ -182,7 +182,7 @@ void RimEnsembleStatistics::defineUiOrdering( QString uiConfigName, caf::PdmUiOr auto crossPlotGroup = uiOrdering.addNewGroup( "Cross Plot" ); crossPlotGroup->add( &m_crossPlotCurvesBinCount ); - crossPlotGroup->add( &m_crossPlotCurvesStatisticsSampleCountThresholdPerBin ); + crossPlotGroup->add( &m_crossPlotCurvesStatisticsRealizationCountThresholdPerBin ); if ( m_showColorField ) uiOrdering.add( &m_color ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatistics.h b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatistics.h index d4702fb2ac..fc31796f68 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatistics.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatistics.h @@ -53,7 +53,7 @@ public: bool includeIncompleteCurves() const { return m_includeIncompleteCurves; } int crossPlotCurvesBinCount() const; - int crossPlotCurvesSampleCountThresholdPerBin() const; + int crossPlotRealizationCountThresholdPerBin() const; void disableP10Curve( bool disable ); void disableP50Curve( bool disable ); @@ -81,7 +81,7 @@ private: // Ensemble cross plot settings caf::PdmField m_crossPlotCurvesBinCount; - caf::PdmField m_crossPlotCurvesStatisticsSampleCountThresholdPerBin; + caf::PdmField m_crossPlotCurvesStatisticsRealizationCountThresholdPerBin; caf::PdmField m_warningLabel; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.cpp index ec659d422a..6c2496d4c6 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.cpp @@ -30,26 +30,6 @@ #include #include -//-------------------------------------------------------------------------------------------------- -/// Internal constants -//-------------------------------------------------------------------------------------------------- -#define DOUBLE_INF std::numeric_limits::infinity() - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimEnsembleStatisticsCase::RimEnsembleStatisticsCase() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -const std::vector& RimEnsembleStatisticsCase::timeSteps() const -{ - return m_timeSteps; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.h b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.h index 47fc986fd3..0d5a789ebf 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleStatisticsCase.h @@ -33,10 +33,6 @@ class RifEclipseSummaryAddress; class RimEnsembleStatisticsCase : public RimSummaryCase, public RifSummaryReaderInterface { public: - RimEnsembleStatisticsCase(); - - const std::vector& timeSteps() const; - bool hasP10Data() const; bool hasP50Data() const; bool hasP90Data() const; diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimObjectiveFunctionTools.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimObjectiveFunctionTools.cpp index 477b966af1..52311ef86b 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimObjectiveFunctionTools.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimObjectiveFunctionTools.cpp @@ -43,7 +43,7 @@ RimCustomObjectiveFunctionWeight* RimObjectiveFunctionTools::addWeight( RimCusto } else { - candidateAdr = newWeight->parentCurveSet()->summaryAddress(); + candidateAdr = newWeight->parentCurveSet()->summaryAddressY(); } auto nativeQuantityName = RimObjectiveFunctionTools::nativeQuantityName( candidateAdr.vectorName() ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryAddressModifier.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryAddressModifier.cpp index 01f1c99e57..b62de94173 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryAddressModifier.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryAddressModifier.cpp @@ -81,7 +81,7 @@ std::vector RimSummaryAddressModifier::createEclipseSu RifEclipseSummaryAddress RimSummaryAddressModifier::address() const { if ( m_curve ) return m_curve->summaryAddressY(); - if ( m_curveSet ) return m_curveSet->summaryAddress(); + if ( m_curveSet ) return m_curveSet->summaryAddressY(); return {}; } @@ -92,7 +92,7 @@ RifEclipseSummaryAddress RimSummaryAddressModifier::address() const void RimSummaryAddressModifier::setAddress( const RifEclipseSummaryAddress& address ) { if ( m_curve ) m_curve->setSummaryAddressY( address ); - if ( m_curveSet ) m_curveSet->setSummaryAddressAndStatisticsFlag( address ); + if ( m_curveSet ) m_curveSet->setSummaryAddressYAndStatisticsFlag( address ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp index 76b2ff488e..24d7841dae 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.cpp @@ -141,6 +141,8 @@ QString RimSummaryCurvesData::createTextForExport( const std::vector& curves ) +{ + QString text; + + for ( const auto& curve : curves ) + { + const auto curveAddress = curve->curveAddress(); + const auto xAddress = curveAddress.summaryAddressX(); + const auto yAddress = curveAddress.summaryAddressY(); + + const auto xValues = curve->valuesX(); + const auto yValues = curve->valuesY(); + + if ( xValues.size() == yValues.size() ) + { + text += curve->curveExportDescription( {} ) + "\n"; + + text += + QString( "%1\t%2\n" ).arg( QString::fromStdString( xAddress.vectorName() ) ).arg( QString::fromStdString( yAddress.vectorName() ) ); + + for ( size_t i = 0; i < xValues.size(); i++ ) + { + QString line; + line += QString::number( xValues[i], 'g', RimSummaryPlot::precision() ); + line += "\t"; + line += QString::number( yValues[i], 'g', RimSummaryPlot::precision() ); + line += "\n"; + + text += line; + } + } + + text += "\n"; + } + + return text; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h index c19509a1bf..4aa19cc99c 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryCurvesData.h @@ -66,6 +66,8 @@ public: RiaDefines::DateTimePeriod resamplingPeriod, bool showTimeAsLongString ); + static QString createTextForCrossPlotCurves( const std::vector& curves ); + private: static void populateSummaryCurvesData( std::vector curves, SummaryCurveType curveType, RimSummaryCurvesData* curvesData ); static void populateTimeHistoryCurvesData( std::vector curves, RimSummaryCurvesData* curvesData ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp index 9007522c4d..5fdb5c4fd9 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryMultiPlot.cpp @@ -1591,7 +1591,7 @@ void RimSummaryMultiPlot::appendCurveByStepping( int direction ) for ( auto curveSet : plot->curveSets() ) { - auto address = curveSet->summaryAddress(); + auto address = curveSet->summaryAddressY(); auto sumEns = curveSet->summaryCaseCollection(); int sumEnsId = sumEns->ensembleId(); if ( m_sourceStepping()->stepDimension() == RimSummaryDataSourceStepping::SourceSteppingDimension::ENSEMBLE ) diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index faceefb016..dc5b86bef0 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -120,8 +120,7 @@ struct RimSummaryPlot::CurveInfo /// //-------------------------------------------------------------------------------------------------- RimSummaryPlot::RimSummaryPlot() - : RimPlot() - , curvesChanged( this ) + : curvesChanged( this ) , axisChanged( this ) , plotZoomedByUser( this ) , titleChanged( this ) @@ -336,13 +335,29 @@ QString RimSummaryPlot::asciiDataForPlotExport() const //-------------------------------------------------------------------------------------------------- QString RimSummaryPlot::asciiDataForSummaryPlotExport( RiaDefines::DateTimePeriod resamplingPeriod, bool showTimeAsLongString ) const { - std::vector curves = descendantsIncludingThisOfType(); + std::vector allCurves = descendantsIncludingThisOfType(); + + std::vector crossPlotCurves; + std::vector curves; + for ( auto c : allCurves ) + { + if ( c->axisTypeX() == RiaDefines::HorizontalAxisType::SUMMARY_VECTOR ) + { + crossPlotCurves.push_back( c ); + } + else + { + curves.push_back( c ); + } + } auto gridCurves = m_gridTimeHistoryCurves.childrenByType(); auto asciiCurves = m_asciiDataCurves.childrenByType(); QString text = RimSummaryCurvesData::createTextForExport( curves, asciiCurves, gridCurves, resamplingPeriod, showTimeAsLongString ); + text += RimSummaryCurvesData::createTextForCrossPlotCurves( crossPlotCurves ); + return text; } @@ -828,7 +843,7 @@ void RimSummaryPlot::applyDefaultCurveAppearances( std::vectorsummaryAddress(); + const auto adr = curveSet->summaryAddressY(); if ( adr.isHistoryVector() ) { curveColor = RiaPreferencesSummary::current()->historyCurveContrastColor(); @@ -932,9 +947,11 @@ void RimSummaryPlot::updateNumericalAxis( RiaDefines::PlotAxis plotAxis ) } if ( summaryCurve->axisX() == riuPlotAxis ) { - curveDefs.push_back( RiaSummaryCurveDefinition( summaryCurve->summaryCaseX(), - summaryCurve->summaryAddressX(), - summaryCurve->isEnsembleCurve() ) ); + RiaSummaryCurveDefinition def; + def.setSummaryCaseX( summaryCurve->summaryCaseX() ); + def.setSummaryAddressX( summaryCurve->summaryAddressX() ); + + curveDefs.push_back( def ); } } @@ -942,7 +959,7 @@ void RimSummaryPlot::updateNumericalAxis( RiaDefines::PlotAxis plotAxis ) { if ( curveSet->axisY() == riuPlotAxis ) { - RiaSummaryCurveDefinition def( curveSet->summaryCaseCollection(), curveSet->summaryAddress() ); + RiaSummaryCurveDefinition def( curveSet->summaryCaseCollection(), curveSet->summaryAddressY() ); curveDefs.push_back( def ); } if ( curveSet->axisX() == riuPlotAxis ) @@ -1041,15 +1058,13 @@ void RimSummaryPlot::updateTimeAxis( RimSummaryTimeAxisProperties* timeAxisPrope //-------------------------------------------------------------------------------------------------- void RimSummaryPlot::updateZoomForAxis( RimPlotAxisPropertiesInterface* axisProperties ) { - RimSummaryTimeAxisProperties* timeAxisProps = dynamic_cast( axisProperties ); - if ( timeAxisProps ) + if ( auto timeAxisProps = dynamic_cast( axisProperties ) ) { updateZoomForTimeAxis( timeAxisProps ); return; } - RimPlotAxisProperties* axisProps = dynamic_cast( axisProperties ); - if ( axisProps ) + if ( auto axisProps = dynamic_cast( axisProperties ) ) { updateZoomForNumericalAxis( axisProps ); return; @@ -2503,7 +2518,7 @@ RimSummaryPlot::CurveInfo RimSummaryPlot::handleSummaryAddressDrop( RimSummaryAd for ( auto& curve : curveSets() ) { - const auto addr = curve->summaryAddress(); + const auto addr = curve->summaryAddressY(); dataVectorMap[addr].insert( curve->summaryCaseCollection() ); } @@ -2651,15 +2666,15 @@ RimEnsembleCurveSet* RimSummaryPlot::addNewEnsembleCurve( const RiaSummaryCurveA auto* curveSet = new RimEnsembleCurveSet(); curveSet->setSummaryCaseCollection( ensemble ); - curveSet->setSummaryAddressAndStatisticsFlag( address.summaryAddressY() ); + curveSet->setSummaryAddressYAndStatisticsFlag( address.summaryAddressY() ); curveSet->setCurveAddress( address ); cvf::Color3f curveColor = - RimSummaryCurveAppearanceCalculator::computeTintedCurveColorForAddress( curveSet->summaryAddress(), + RimSummaryCurveAppearanceCalculator::computeTintedCurveColorForAddress( curveSet->summaryAddressY(), static_cast( ensembleCurveSetCollection()->curveSetCount() ) ); - auto adr = curveSet->summaryAddress(); + auto adr = curveSet->summaryAddressY(); if ( adr.isHistoryVector() ) curveColor = RiaPreferencesSummary::current()->historyCurveContrastColor(); curveSet->setColor( curveColor ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp index c61555ba28..fd932b9a08 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimSummaryPlotSourceStepping.cpp @@ -362,17 +362,26 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi( const caf::PdmFieldHandle* bool triggerLoadDataAndUpdate = false; - auto updateEnsembleAddresses = [&doZoomAll, &oldValue, &newValue]( const std::vector& curveSets ) + auto updateEnsembleAddresses = + [&doZoomAll, &oldValue, &newValue]( const std::vector& curveSets, SummaryCategory categoryToUpdate ) { for ( auto curveSet : curveSets ) { auto curveAdr = curveSet->curveAddress(); auto yAddressToModify = curveAdr.summaryAddressY(); - RimDataSourceSteppingTools::updateQuantityIfMatching( oldValue, newValue, yAddressToModify ); - auto xAddressToModify = curveAdr.summaryAddressX(); - RimDataSourceSteppingTools::updateQuantityIfMatching( oldValue, newValue, xAddressToModify ); + + if ( categoryToUpdate != SummaryCategory::SUMMARY_INVALID ) + { + RimDataSourceSteppingTools::updateAddressIfMatching( oldValue, newValue, categoryToUpdate, yAddressToModify ); + RimDataSourceSteppingTools::updateAddressIfMatching( oldValue, newValue, categoryToUpdate, xAddressToModify ); + } + else + { + RimDataSourceSteppingTools::updateQuantityIfMatching( oldValue, newValue, yAddressToModify ); + RimDataSourceSteppingTools::updateQuantityIfMatching( oldValue, newValue, xAddressToModify ); + } curveSet->setCurveAddress( RiaSummaryCurveAddress( xAddressToModify, yAddressToModify ) ); curveSet->updateConnectedEditors(); @@ -451,7 +460,7 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi( const caf::PdmFieldHandle* if ( dataSourceSteppingObject() ) { - updateEnsembleAddresses( dataSourceSteppingObject()->curveSets() ); + updateEnsembleAddresses( dataSourceSteppingObject()->curveSets(), SummaryCategory::SUMMARY_INVALID ); } m_vectorName.uiCapability()->updateConnectedEditors(); @@ -516,7 +525,7 @@ void RimSummaryPlotSourceStepping::fieldChangedByUi( const caf::PdmFieldHandle* if ( dataSourceSteppingObject() ) { - updateEnsembleAddresses( dataSourceSteppingObject()->curveSets() ); + updateEnsembleAddresses( dataSourceSteppingObject()->curveSets(), summaryCategoryToModify ); } triggerLoadDataAndUpdate = true; @@ -675,7 +684,7 @@ std::set RimSummaryPlotSourceStepping::addressesForCur { for ( auto curveSet : dataSourceSteppingObject()->curveSets() ) { - addresses.insert( curveSet->summaryAddress() ); + addresses.insert( curveSet->summaryAddressY() ); } std::vector curves; diff --git a/ApplicationLibCode/UserInterface/RiuSummaryPlot.cpp b/ApplicationLibCode/UserInterface/RiuSummaryPlot.cpp index 95ae3a402e..5e0de6acfc 100644 --- a/ApplicationLibCode/UserInterface/RiuSummaryPlot.cpp +++ b/ApplicationLibCode/UserInterface/RiuSummaryPlot.cpp @@ -97,7 +97,7 @@ void RiuSummaryPlot::showContextMenu( QPoint pos ) ensemble = clickedEnsembleCurveSet->summaryCaseCollection(); if ( ensemble && ensemble->isEnsemble() ) { - clickedQuantityName = QString::fromStdString( clickedEnsembleCurveSet->summaryAddress().uiText() ); + clickedQuantityName = QString::fromStdString( clickedEnsembleCurveSet->summaryAddressY().uiText() ); if ( curveClicked ) { @@ -127,7 +127,7 @@ void RiuSummaryPlot::showContextMenu( QPoint pos ) std::vector allCurveSetsInPlot = summaryPlot->descendantsOfType(); for ( auto curveSet : allCurveSetsInPlot ) { - allQuantityNamesInPlot.push_back( QString::fromStdString( curveSet->summaryAddress().uiText() ) ); + allQuantityNamesInPlot.push_back( QString::fromStdString( curveSet->summaryAddressY().uiText() ) ); } } else @@ -162,7 +162,7 @@ void RiuSummaryPlot::showContextMenu( QPoint pos ) { menuBuilder.subMenuStart( "Cross Plots", *caf::IconProvider( ":/CorrelationCrossPlot16x16.png" ).icon() ); std::vector> ensembleParameters = - ensemble->parameterCorrelations( clickedEnsembleCurveSet->summaryAddress(), timeStep ); + ensemble->parameterCorrelations( clickedEnsembleCurveSet->summaryAddressY(), timeStep ); std::sort( ensembleParameters.begin(), ensembleParameters.end(), []( const std::pair& lhs, const std::pair& rhs )