Add Sumo summary ensemble and summary case

Add feature to create ensemble from a sumo data source
This commit is contained in:
Magne Sjaastad
2024-07-05 09:06:16 +02:00
parent d751ce4ce0
commit 31d653bce7
28 changed files with 1517 additions and 11 deletions

View File

@@ -0,0 +1,14 @@
set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimSummaryEnsembleSumo.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCaseSumo.h
${CMAKE_CURRENT_LIST_DIR}/RimSummarySumoDataSource.h
)
set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimSummaryEnsembleSumo.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryCaseSumo.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummarySumoDataSource.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
list(APPEND CODE_SOURCE_FILES ${SOURCE_GROUP_SOURCE_FILES})

View File

@@ -0,0 +1,179 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024 Equinor 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 "RimSummaryCaseSumo.h"
#include "RimSummaryEnsembleSumo.h"
#include "cafPdmObjectScriptingCapability.h"
CAF_PDM_SOURCE_INIT( RimSummaryCaseSumo, "RimSummaryCaseSumo" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCaseSumo::RimSummaryCaseSumo()
: m_realizationNumber( -1 )
{
CAF_PDM_InitScriptableObject( "Sumo Realization", ":/SummaryCase.svg" );
m_ensemble = nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseSumo::createSummaryReaderInterface()
{
// Nothing to do here
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifSummaryReaderInterface* RimSummaryCaseSumo::summaryReader()
{
return this;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<time_t> RimSummaryCaseSumo::timeSteps( const RifEclipseSummaryAddress& resultAddress ) const
{
return m_timeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<bool, std::vector<double>> RimSummaryCaseSumo::values( const RifEclipseSummaryAddress& resultAddress ) const
{
auto it = m_values.find( resultAddress );
if ( it == m_values.end() && m_ensemble )
{
// We can be asked for a result that is not available in the cache. In this case we need to load the data from the ensemble.
m_ensemble->loadSummaryData( resultAddress );
it = m_values.find( resultAddress );
}
if ( it != m_values.end() )
{
std::vector<double> doubleValues;
doubleValues.reserve( it->second.size() );
for ( auto value : it->second )
{
doubleValues.push_back( value );
}
return { true, doubleValues };
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RimSummaryCaseSumo::unitName( const RifEclipseSummaryAddress& resultAddress ) const
{
if ( m_ensemble ) return m_ensemble->unitName( resultAddress );
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::EclipseUnitSystem RimSummaryCaseSumo::unitSystem() const
{
if ( m_ensemble ) return m_ensemble->unitSystem();
return RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseSumo::setEnsemble( RimSummaryEnsembleSumo* ensemble )
{
m_ensemble = ensemble;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseSumo::setValues( const std::vector<time_t>& timeSteps,
const RifEclipseSummaryAddress& resultAddress,
const std::vector<float>& values )
{
m_timeSteps = timeSteps;
m_values[resultAddress] = values;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int32_t RimSummaryCaseSumo::realizationNumber() const
{
return m_realizationNumber;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseSumo::setRealizationNumber( int32_t realizationNumber )
{
m_realizationNumber = realizationNumber;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCaseSumo::realizationName() const
{
return m_realizationName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseSumo::setRealizationName( const QString& realizationName )
{
m_realizationName = realizationName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummaryCaseSumo::caseName() const
{
return realizationName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseSumo::buildMetaData()
{
if ( m_ensemble )
{
auto addresses = m_ensemble->allResultAddresses();
m_allResultAddresses = addresses;
}
}

View File

@@ -0,0 +1,67 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024 Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RifSummaryReaderInterface.h"
#include "RimSummaryCase.h"
#include "cafPdmPointer.h"
class RimSummaryEnsembleSumo;
//==================================================================================================
//
//
//
//==================================================================================================
class RimSummaryCaseSumo : public RimSummaryCase, public RifSummaryReaderInterface
{
CAF_PDM_HEADER_INIT;
public:
RimSummaryCaseSumo();
void setEnsemble( RimSummaryEnsembleSumo* ensemble );
void setValues( const std::vector<time_t>& timeSteps, const RifEclipseSummaryAddress& resultAddress, const std::vector<float>& values );
int32_t realizationNumber() const;
void setRealizationNumber( int32_t realizationNumber );
QString realizationName() const;
void setRealizationName( const QString& realizationName );
void createSummaryReaderInterface() override;
RifSummaryReaderInterface* summaryReader() override;
std::vector<time_t> timeSteps( const RifEclipseSummaryAddress& resultAddress ) const override;
std::pair<bool, std::vector<double>> values( const RifEclipseSummaryAddress& resultAddress ) const override;
std::string unitName( const RifEclipseSummaryAddress& resultAddress ) const override;
RiaDefines::EclipseUnitSystem unitSystem() const override;
protected:
QString caseName() const override;
void buildMetaData() override;
private:
caf::PdmPointer<RimSummaryEnsembleSumo> m_ensemble;
QString m_realizationName;
int32_t m_realizationNumber;
std::vector<time_t> m_timeSteps;
std::map<RifEclipseSummaryAddress, std::vector<float>> m_values;
};

View File

@@ -0,0 +1,421 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024 Equinor 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 "RimSummaryEnsembleSumo.h"
#include "RiaApplication.h"
#include "RiaLogging.h"
#include "RiaSummaryDefines.h"
#include "RiaSummaryTools.h"
#include "RiaTimeTTools.h"
#include "RifArrowTools.h"
#include "RifByteArrayArrowRandomAccessFile.h"
#include "RifEclipseSummaryAddress.h"
#include "Cloud/RimCloudDataSourceCollection.h"
#include "RimSummaryCaseSumo.h"
#include "RimSummarySumoDataSource.h"
CAF_PDM_SOURCE_INIT( RimSummaryEnsembleSumo, "RimSummaryEnsembleSumo" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryEnsembleSumo::RimSummaryEnsembleSumo()
{
CAF_PDM_InitObject( "Sumo Ensemble", ":/SummaryCase.svg", "", "The Base Class for all Summary Cases" );
CAF_PDM_InitFieldNoDefault( &m_sumoDataSource, "SumoDataSource", "Sumo Data Source" );
// Disable IO for cases, as the reconstruction is done by loading data from Sumo
// Will also reduce the amount of data stored in the project file
m_cases.xmlCapability()->disableIO();
setAsEnsemble( true );
m_sumoConnector = RiaApplication::instance()->makeSumoConnector();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::setSumoDataSource( RimSummarySumoDataSource* sumoDataSource )
{
m_sumoDataSource = sumoDataSource;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::updateName()
{
if ( m_sumoDataSource() )
{
setName( m_sumoDataSource()->name() );
}
else
{
setName( "No Sumo Data Source" );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RimSummaryEnsembleSumo::unitName( const RifEclipseSummaryAddress& resultAddress )
{
// TODO: Not implemented yet. Need to get the unit name from the Sumo data source
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::EclipseUnitSystem RimSummaryEnsembleSumo::unitSystem() const
{
// TODO: Not implemented yet. Need to get the unit name from the Sumo data source
return RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress> RimSummaryEnsembleSumo::allResultAddresses() const
{
return m_resultAddresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::loadSummaryData( const RifEclipseSummaryAddress& resultAddress )
{
if ( resultAddress.category() == SummaryCategory::SUMMARY_ENSEMBLE_STATISTICS ) return;
if ( !m_sumoDataSource() ) return;
auto resultText = QString::fromStdString( resultAddress.toEclipseTextAddress() );
auto sumoCaseId = m_sumoDataSource->caseId();
auto sumoEnsembleName = m_sumoDataSource->ensembleName();
auto key = ParquetKey{ sumoCaseId, sumoEnsembleName, resultText };
if ( m_parquetTable.find( key ) == m_parquetTable.end() )
{
auto contents = loadParquetData( key );
arrow::MemoryPool* pool = arrow::default_memory_pool();
std::shared_ptr<arrow::io::RandomAccessFile> input = std::make_shared<RifByteArrayArrowRandomAccessFile>( contents );
std::shared_ptr<arrow::Table> table;
std::unique_ptr<parquet::arrow::FileReader> arrow_reader;
if ( parquet::arrow::OpenFile( input, pool, &arrow_reader ).ok() )
{
if ( arrow_reader->ReadTable( &table ).ok() )
{
RiaLogging::info( "Parquet: Read table" );
}
else
{
RiaLogging::warning( "Parquet: Error detected during parsing of table" );
}
}
else
{
RiaLogging::warning( "Parquet: Not able to open data stream" );
}
m_parquetTable[key] = table;
distributeDataToRealizations( resultAddress, table );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QByteArray RimSummaryEnsembleSumo::loadParquetData( const ParquetKey& parquetKey )
{
if ( !m_sumoConnector ) return {};
return m_sumoConnector->requestParquetDataBlocking( SumoCaseId( parquetKey.caseId ), parquetKey.ensembleId, parquetKey.vectorName );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::distributeDataToRealizations( const RifEclipseSummaryAddress& resultAddress, std::shared_ptr<arrow::Table> table )
{
if ( !table )
{
RiaLogging::warning( "Failed to load table" );
return;
}
{
// print header information
QString txt = "Column Names: ";
for ( std::string columnName : table->ColumnNames() )
{
txt += QString::fromStdString( columnName ) + " ";
}
RiaLogging::info( txt );
}
std::vector<time_t> timeSteps;
std::vector<int16_t> realizations;
std::vector<float> values;
{
const std::string columnName = "DATE";
std::shared_ptr<arrow::ChunkedArray> column = table->GetColumnByName( columnName );
if ( column && column->type()->id() == arrow::Type::TIMESTAMP )
{
auto timeColumn = RifArrowTools::chunkedArrayToVector<arrow::Int64Array, int64_t>( column );
timeSteps = std::vector<time_t>( timeColumn.size() );
for ( size_t i = 0; i < timeColumn.size(); ++i )
{
timeSteps[i] = RiaTimeTTools::fromDouble( timeColumn[i] );
}
}
else
{
RiaLogging::warning( "Failed to find DATE column" );
return;
}
}
{
const std::string columnName = "REAL";
std::shared_ptr<arrow::ChunkedArray> column = table->GetColumnByName( columnName );
if ( column && column->type()->id() == arrow::Type::INT16 )
{
realizations = RifArrowTools::chunkedArrayToVector<arrow::Int16Array, int16_t>( column );
}
else
{
RiaLogging::warning( "Failed to find realization column" );
return;
}
}
{
const std::string columnName = resultAddress.toEclipseTextAddress();
std::shared_ptr<arrow::ChunkedArray> column = table->GetColumnByName( columnName );
if ( column && column->type()->id() == arrow::Type::FLOAT )
{
values = RifArrowTools::chunkedArrayToVector<arrow::FloatArray, float>( column );
}
else
{
RiaLogging::warning( "Failed to find values column" );
return;
}
}
// find unique realizations
std::set<int16_t> uniqueRealizations;
for ( auto realizationNumber : realizations )
{
uniqueRealizations.insert( realizationNumber );
}
// find start and end index for a given realization number
std::map<int16_t, std::pair<size_t, size_t>> realizationIndex;
for ( size_t i = 0; i < realizations.size(); ++i )
{
auto realizationNumber = realizations[i];
uniqueRealizations.insert( realizationNumber );
if ( realizationIndex.find( realizationNumber ) == realizationIndex.end() )
{
realizationIndex[realizationNumber] = { i, i };
}
else
{
realizationIndex[realizationNumber].second = i;
}
}
auto findSummaryCase = [this]( int16_t realizationNumber ) -> RimSummaryCaseSumo*
{
for ( auto sumCase : allSummaryCases() )
{
auto sumCaseSumo = dynamic_cast<RimSummaryCaseSumo*>( sumCase );
if ( sumCaseSumo->realizationNumber() == realizationNumber ) return sumCaseSumo;
}
return nullptr;
};
for ( auto realizationNumber : uniqueRealizations )
{
auto summaryCase = findSummaryCase( realizationNumber );
if ( !summaryCase ) continue;
auto start = realizationIndex[realizationNumber].first;
auto end = realizationIndex[realizationNumber].second;
std::vector<time_t> realizationTimeSteps( timeSteps.begin() + start, timeSteps.begin() + end );
std::vector<float> realizationValues( values.begin() + start, values.begin() + end );
summaryCase->setValues( realizationTimeSteps, resultAddress, realizationValues );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::buildMetaData()
{
for ( auto summaryCase : allSummaryCases() )
{
summaryCase->summaryReader()->buildMetaData();
}
RimSummaryCaseCollection::buildMetaData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
uiOrdering.add( &m_sumoDataSource );
auto group = uiOrdering.addNewGroup( "General" );
RimSummaryCaseCollection::defineUiOrdering( uiConfigName, *group );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimSummaryEnsembleSumo::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_sumoDataSource )
{
for ( const auto& sumoDataSource : RimCloudDataSourceCollection::instance()->sumoDataSources() )
{
options.push_back( { sumoDataSource->name(), sumoDataSource } );
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
{
if ( changedField == &m_sumoDataSource )
{
clearCachedData();
updateResultAddresses();
updateName();
buildMetaData();
updateConnectedEditors();
RiaSummaryTools::reloadSummaryEnsemble( this );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::updateResultAddresses()
{
m_resultAddresses.clear();
if ( !m_sumoDataSource() ) return;
auto vectorNames = m_sumoDataSource->vectorNames();
for ( auto vectorName : vectorNames )
{
auto adr = RifEclipseSummaryAddress::fromEclipseTextAddress( vectorName.toStdString() );
m_resultAddresses.insert( adr );
}
auto caseName = m_sumoDataSource->caseId().get();
auto ensName = m_sumoDataSource->ensembleName();
RiaLogging::info( QString( "Case: %1, ens: %2, vector count: %3" ).arg( caseName ).arg( ensName ).arg( m_resultAddresses.size() ) );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::clearCachedData()
{
m_resultAddresses.clear();
m_parquetTable.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleSumo::onLoadDataAndUpdate()
{
if ( m_sumoDataSource() )
{
auto realizationIds = m_sumoDataSource->realizationIds();
if ( realizationIds.size() != m_cases.size() )
{
m_cases.deleteChildren();
for ( auto realId : realizationIds )
{
auto realization = new RimSummaryCaseSumo();
realization->setEnsemble( this );
realization->setRealizationName( QString( "real-%1" ).arg( realId ) );
realization->setRealizationNumber( realId.toInt() );
realization->updateAutoShortName();
realization->setShowVectorItemsInProjectTree( m_cases.empty() );
// Create realization parameters, required to make derived ensemble cases work
// See RimDerivedEnsembleCaseCollection::createDerivedEnsembleCases()
auto parameters = std::shared_ptr<RigCaseRealizationParameters>( new RigCaseRealizationParameters() );
int realizationNumber = realId.toInt();
parameters->setRealizationNumber( realizationNumber );
parameters->addParameter( RiaDefines::summaryRealizationNumber(), realizationNumber );
realization->setCaseRealizationParameters( parameters );
m_cases.push_back( realization );
}
}
}
updateName();
updateResultAddresses();
buildMetaData();
// call the base class method after data has been loaded
RimSummaryCaseCollection::onLoadDataAndUpdate();
}

View File

@@ -0,0 +1,92 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024 Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimSummaryCaseCollection.h"
#include "Cloud/RiaSumoConnector.h"
#include "cafPdmPtrField.h"
#include <QPointer>
class RimSummarySumoDataSource;
//==================================================================================================
//
//
//
//==================================================================================================
struct ParquetKey
{
SumoCaseId caseId;
QString ensembleId;
QString vectorName;
auto operator<=>( const ParquetKey& other ) const
{
return std::tie( caseId, ensembleId, vectorName ) <=> std::tie( other.caseId, other.ensembleId, other.vectorName );
}
};
namespace arrow
{
class Table;
}
class RimSummaryEnsembleSumo : public RimSummaryCaseCollection
{
CAF_PDM_HEADER_INIT;
public:
RimSummaryEnsembleSumo();
void setSumoDataSource( RimSummarySumoDataSource* sumoDataSource );
void updateName();
void loadSummaryData( const RifEclipseSummaryAddress& resultAddress );
std::string unitName( const RifEclipseSummaryAddress& resultAddress );
RiaDefines::EclipseUnitSystem unitSystem() const;
std::set<RifEclipseSummaryAddress> allResultAddresses() const;
protected:
void onLoadDataAndUpdate() override;
private:
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
void updateResultAddresses();
void clearCachedData();
QByteArray loadParquetData( const ParquetKey& parquetKey );
void distributeDataToRealizations( const RifEclipseSummaryAddress& resultAddress, std::shared_ptr<arrow::Table> table );
void buildMetaData();
private:
caf::PdmPtrField<RimSummarySumoDataSource*> m_sumoDataSource;
QPointer<RiaSumoConnector> m_sumoConnector;
std::set<RifEclipseSummaryAddress> m_resultAddresses;
std::map<ParquetKey, std::shared_ptr<arrow::Table>> m_parquetTable;
};

View File

@@ -0,0 +1,207 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024 Equinor 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 "RimSummarySumoDataSource.h"
#include "RiaStdStringTools.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "cafPdmUiTreeSelectionEditor.h"
CAF_PDM_SOURCE_INIT( RimSummarySumoDataSource, "RimSummarySumoDataSource" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummarySumoDataSource::RimSummarySumoDataSource()
{
CAF_PDM_InitObject( "Sumo Data Source", ":/SummaryCase.svg" );
CAF_PDM_InitFieldNoDefault( &m_caseId, "CaseId", "Case Id" );
CAF_PDM_InitFieldNoDefault( &m_caseName, "CaseName", "Case Name" );
CAF_PDM_InitFieldNoDefault( &m_ensembleName, "EnsembleName", "Ensemble Name" );
CAF_PDM_InitFieldNoDefault( &m_customName, "CustomName", "Custom Name" );
CAF_PDM_InitFieldNoDefault( &m_realizationIds, "RealizationIds", "Realizations Ids" );
m_realizationIds.uiCapability()->setUiHidden( true );
CAF_PDM_InitFieldNoDefault( &m_realizationInfo, "NameProxy", "Realization Info" );
m_realizationInfo.registerGetMethod( this, &RimSummarySumoDataSource::realizationInfoText );
CAF_PDM_InitFieldNoDefault( &m_vectorNames, "VectorNames", "Vector Names" );
m_vectorNames.uiCapability()->setUiReadOnly( true );
setDeletable( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
SumoCaseId RimSummarySumoDataSource::caseId() const
{
return SumoCaseId( m_caseId() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::setCaseId( const SumoCaseId& caseId )
{
m_caseId = caseId.get();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummarySumoDataSource::caseName() const
{
return m_caseName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::setCaseName( const QString& caseName )
{
m_caseName = caseName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummarySumoDataSource::ensembleName() const
{
return m_ensembleName();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::setEnsembleName( const QString& ensembleName )
{
m_ensembleName = ensembleName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RimSummarySumoDataSource::realizationIds() const
{
return m_realizationIds();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::setRealizationIds( const std::vector<QString>& realizationIds )
{
m_realizationIds = realizationIds;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RimSummarySumoDataSource::vectorNames() const
{
return m_vectorNames();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::setVectorNames( const std::vector<QString>& vectorNames )
{
m_vectorNames = vectorNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::updateName()
{
if ( !m_customName().isEmpty() )
{
setName( m_customName() );
return;
}
auto name = QString( "%1 (%2)" ).arg( ensembleName(), caseName() );
setName( name );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
{
menuBuilder.addCmdFeature( "RicCreateSumoEnsembleFeature" );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
{
if ( field == &m_vectorNames )
{
if ( auto attr = dynamic_cast<caf::PdmUiTreeSelectionEditorAttribute*>( attribute ) )
{
attr->showCheckBoxes = false;
attr->showContextMenu = false;
attr->showToggleAllCheckbox = false;
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummarySumoDataSource::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
auto group = uiOrdering.addNewGroup( "General" );
group->add( nameField() );
group->add( &m_caseId );
group->add( &m_caseName );
group->add( &m_ensembleName );
group->add( &m_customName );
auto summaryInfo = uiOrdering.addNewGroup( "Info" );
summaryInfo->add( &m_realizationInfo );
summaryInfo->add( &m_vectorNames );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimSummarySumoDataSource::realizationInfoText() const
{
std::vector<int> intValues;
for ( const auto& realizationId : realizationIds() )
{
bool ok = false;
int value = realizationId.toInt( &ok );
if ( ok )
{
intValues.push_back( value );
}
}
auto rangeString = RiaStdStringTools::formatRangeSelection( intValues );
return QString::fromStdString( rangeString );
}

View File

@@ -0,0 +1,73 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024 Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimNamedObject.h"
#include "Cloud/RiaSumoConnector.h"
#include "cafPdmProxyValueField.h"
//==================================================================================================
//
//
//
//==================================================================================================
class RimSummarySumoDataSource : public RimNamedObject
{
CAF_PDM_HEADER_INIT;
public:
RimSummarySumoDataSource();
SumoCaseId caseId() const;
void setCaseId( const SumoCaseId& caseId );
QString caseName() const;
void setCaseName( const QString& caseName );
QString ensembleName() const;
void setEnsembleName( const QString& ensembleName );
std::vector<QString> realizationIds() const;
void setRealizationIds( const std::vector<QString>& realizationIds );
std::vector<QString> vectorNames() const;
void setVectorNames( const std::vector<QString>& vectorNames );
void updateName();
private:
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
QString realizationInfoText() const;
private:
caf::PdmField<QString> m_caseId;
caf::PdmField<QString> m_caseName;
caf::PdmField<QString> m_ensembleName;
caf::PdmField<QString> m_customName;
caf::PdmProxyValueField<QString> m_realizationInfo;
caf::PdmField<std::vector<QString>> m_realizationIds;
caf::PdmField<std::vector<QString>> m_vectorNames;
};