#3318 Plot editor performance. Several performance fixes

This commit is contained in:
Bjørn Erik Jensen 2018-09-13 12:38:17 +02:00
parent 7d2889c66b
commit b4dd37337a
22 changed files with 294 additions and 48 deletions

View File

@ -37,7 +37,7 @@ public:
RiaSummaryCurveDefinition();
explicit RiaSummaryCurveDefinition(RimSummaryCase* summaryCase,
const RifEclipseSummaryAddress& summaryAddress,
RimSummaryCaseCollection* emsemble = nullptr);
RimSummaryCaseCollection* ensemble = nullptr);
RimSummaryCase* summaryCase() const;
const RifEclipseSummaryAddress& summaryAddress() const;

View File

@ -45,6 +45,14 @@ bool RiaStdStringTools::isNumber(const std::string& s, char decimalPoint)
return (s.find_first_not_of(matchChars) == std::string::npos);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int16_t RiaStdStringTools::toInt16(const std::string& s)
{
return (int16_t)toInt(s);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -33,6 +33,7 @@ public:
static std::string trimString(const std::string& s);
static bool isNumber(const std::string& s, char decimalPoint);
static int16_t toInt16(const std::string& s);
static int toInt(const std::string& s);
static double toDouble(const std::string& s);
static bool containsAlphabetic(const std::string& s);

View File

@ -34,6 +34,8 @@
#include "RimSummaryPlotCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimProject.h"
#include "RimSummaryCaseMainCollection.h"
#include "RiuPlotMainWindow.h"
@ -89,6 +91,23 @@ void RicNewSummaryPlotFeature::onActionTriggered(bool isChecked)
std::vector<caf::PdmObject*> sourcesToSelect(selectedCases.begin(), selectedCases.end());
if (sourcesToSelect.empty() && selectedGroups.empty())
{
const auto allSingleCases = project->firstSummaryCaseMainCollection()->topLevelSummaryCases();
const auto allGroups = project->summaryGroups();
std::vector<RimSummaryCaseCollection*> allEnsembles;
for (const auto group : allGroups) if (group->isEnsemble()) allEnsembles.push_back(group);
if (!allSingleCases.empty())
{
sourcesToSelect.push_back(allSingleCases.front());
}
else if (!allEnsembles.empty())
{
sourcesToSelect.push_back(allEnsembles.front());
}
}
// Append grouped cases
for (auto group : selectedGroups)
{

View File

@ -77,6 +77,7 @@ const QString RicSummaryCurveCreator::CONFIGURATION_NAME = "CurveCreatorCfg";
/// Internal functions
//--------------------------------------------------------------------------------------------------
int ensembleCurveCount(const std::set<RiaSummaryCurveDefinition>& allCurveDefs);
template <typename T> std::vector<T> toVector(const std::set<T>& set);
//--------------------------------------------------------------------------------------------------
///
@ -360,7 +361,9 @@ void RicSummaryCurveCreator::syncPreviewCurvesFromUiSelection()
for (const auto& curve : currentCurvesInPreviewPlot)
{
RimSummaryCase* sumCase = curve->summaryCaseY();
RiaSummaryCurveDefinition curveDef = RiaSummaryCurveDefinition(sumCase, curve->summaryAddressY(), sumCase ? sumCase->ensemble() : nullptr);
if (sumCase->ensemble()) continue;
RiaSummaryCurveDefinition curveDef = RiaSummaryCurveDefinition(sumCase, curve->summaryAddressY());
if (deleteCurveDefs.count(curveDef) > 0) curvesToDelete.insert(curve);
}
}
@ -435,13 +438,13 @@ void RicSummaryCurveCreator::updatePreviewCurvesFromCurveDefinitions(
initCurveAppearanceCalculator(curveLookCalc);
// Delete curves
for (const auto& curveSet : curveSetsToDelete)
if(!curveSetsToDelete.empty())
{
m_previewPlot->ensembleCurveSetCollection()->deleteCurveSet(curveSet);
m_previewPlot->ensembleCurveSetCollection()->deleteCurveSets(toVector(curveSetsToDelete));
}
for (const auto& curve : curvesToDelete)
if(!curvesToDelete.empty())
{
m_previewPlot->deleteCurve(curve);
m_previewPlot->deleteCurves(toVector(curvesToDelete));
}
size_t ensembleCurveCnt = ensembleCurveCount(allCurveDefsToDisplay);
@ -1008,3 +1011,11 @@ int ensembleCurveCount(const std::set<RiaSummaryCurveDefinition>& allCurveDefs)
return std::count_if(
allCurveDefs.begin(), allCurveDefs.end(), [](const RiaSummaryCurveDefinition& def) { return def.isEnsembleCurve(); });
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template <typename T> std::vector<T> toVector(const std::set<T>& set)
{
return std::vector<T>(set.begin(), set.end());
}

View File

@ -23,6 +23,8 @@
#include "RicSummaryCurveCreator.h"
#include "RicSummaryCurveCreatorSplitterUi.h"
#include "RifReaderEclipseSummary.h"
#include "RiuPlotMainWindow.h"
#include "RiuTools.h"
@ -84,4 +86,5 @@ void RicSummaryCurveCreatorDialog::slotDialogFinished()
{
plotwindow->cleanUpTemporaryWidgets();
}
RifReaderEclipseSummary::purgeCache();
}

View File

@ -43,12 +43,12 @@ RifEclipseSummaryAddress::RifEclipseSummaryAddress(SummaryVarCategory category,
m_aquiferNumber(-1),
m_isErrorResult(false)
{
std::tuple<int, int, int> ijkTuple;
std::pair<int, int> reg2regPair;
std::tuple<int32_t, int32_t, int32_t> ijkTuple;
std::pair<int16_t, int16_t> reg2regPair;
switch (category)
{
case SUMMARY_REGION:
m_regionNumber = RiaStdStringTools::toInt(identifiers[INPUT_REGION_NUMBER]);
m_regionNumber = RiaStdStringTools::toInt16(identifiers[INPUT_REGION_NUMBER]);
break;
case SUMMARY_REGION_2_REGION:
reg2regPair = regionToRegionPairFromUiText(identifiers[INPUT_REGION_2_REGION]);
@ -783,14 +783,14 @@ std::string RifEclipseSummaryAddress::formatUiTextRegionToRegion() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<int, int> RifEclipseSummaryAddress::regionToRegionPairFromUiText(const std::string &s)
std::pair<int16_t, int16_t> RifEclipseSummaryAddress::regionToRegionPairFromUiText(const std::string &s)
{
QStringList r2r = QString().fromStdString(s).trimmed().split(QRegExp("[-]"));
if (r2r.size() != 2) return std::make_pair(-1, -1);
if (r2r.size() != 2) return std::make_pair((int16_t)-1, (int16_t)-1);
return std::make_pair(RiaStdStringTools::toInt(r2r[0].trimmed().toStdString()),
RiaStdStringTools::toInt(r2r[1].trimmed().toStdString()));
return std::make_pair(RiaStdStringTools::toInt16(r2r[0].trimmed().toStdString()),
RiaStdStringTools::toInt16(r2r[1].trimmed().toStdString()));
}
//--------------------------------------------------------------------------------------------------
@ -890,7 +890,6 @@ bool operator!=(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAd
//--------------------------------------------------------------------------------------------------
bool operator<(const RifEclipseSummaryAddress& first, const RifEclipseSummaryAddress& second)
{
if(first.category() != second.category()) return first.category() < second.category();
if(first.quantityName() != second.quantityName()) return first.quantityName() < second.quantityName();
switch(first.category())

View File

@ -39,7 +39,7 @@ class RifEclipseSummaryAddress
public:
// Based on list in ecl_smspec.c and list of types taken from Eclipse Reference Manual ecl_rm_2011.1.pdf
enum SummaryVarCategory
enum SummaryVarCategory : int8_t
{
SUMMARY_INVALID,
SUMMARY_FIELD,
@ -91,16 +91,16 @@ public:
RifEclipseSummaryAddress(SummaryVarCategory category,
const std::string& quantityName,
int regionNumber,
int regionNumber2,
int16_t regionNumber,
int16_t regionNumber2,
const std::string& wellGroupName,
const std::string& wellName,
int wellSegmentNumber,
int16_t wellSegmentNumber,
const std::string& lgrName,
int cellI,
int cellJ,
int cellK,
int aquiferNumber,
int32_t cellI,
int32_t cellJ,
int32_t cellK,
int16_t aquiferNumber,
bool isErrorResult):
m_variableCategory(category),
m_quantityName(quantityName),
@ -172,34 +172,33 @@ public:
void setQuantityName(const std::string& quantity) { m_quantityName = quantity; }
void setWellName(const std::string& wellName) { m_wellName = wellName; }
void setWellGroupName(const std::string& wellGroupName) { m_wellGroupName = wellGroupName; }
void setRegion(int region) { m_regionNumber = region; }
void setAquiferNumber(int aquiferNumber) { m_aquiferNumber = aquiferNumber; }
void setRegion(int region) { m_regionNumber = (int16_t)region; }
void setAquiferNumber(int aquiferNumber) { m_aquiferNumber = (int16_t)aquiferNumber; }
void setAsErrorResult() { m_isErrorResult = true; }
bool isErrorResult() const { return m_isErrorResult; }
bool hasAccumulatedData() const;
private:
bool isValidEclipseCategory() const;
static std::string baseQuantityName(const std::string& quantityName);
std::string formatUiTextIJK() const;
static std::tuple<int, int, int> ijkTupleFromUiText(const std::string &s);
std::string formatUiTextRegionToRegion() const;
std::pair<int, int> regionToRegionPairFromUiText(const std::string &s);
bool isValidEclipseCategory() const;
static std::string baseQuantityName(const std::string& quantityName);
std::string formatUiTextIJK() const;
static std::tuple<int32_t, int32_t, int32_t> ijkTupleFromUiText(const std::string &s);
std::string formatUiTextRegionToRegion() const;
std::pair<int16_t, int16_t> regionToRegionPairFromUiText(const std::string &s);
SummaryVarCategory m_variableCategory;
std::string m_quantityName;
int m_regionNumber;
int m_regionNumber2;
std::string m_wellGroupName;
std::string m_wellName;
int m_wellSegmentNumber;
std::string m_lgrName;
int m_cellI;
int m_cellJ;
int m_cellK;
int m_aquiferNumber;
int32_t m_cellI;
int32_t m_cellJ;
int32_t m_cellK;
int16_t m_regionNumber;
int16_t m_regionNumber2;
int16_t m_wellSegmentNumber;
int16_t m_aquiferNumber;
SummaryVarCategory m_variableCategory;
bool m_isErrorResult;
};

View File

@ -105,7 +105,7 @@ RifReaderEclipseSummary::RifReaderEclipseSummary()
: m_ecl_sum(nullptr),
m_ecl_SmSpec(nullptr)
{
m_valuesCache.reset(new ValuesCache());
}
//--------------------------------------------------------------------------------------------------
@ -384,7 +384,12 @@ bool RifReaderEclipseSummary::values(const RifEclipseSummaryAddress& resultAddre
values->clear();
values->reserve(timeStepCount());
if (m_ecl_SmSpec)
const std::vector<double>& cachedValues = m_valuesCache->getValues(resultAddress);
if (!cachedValues.empty())
{
values->insert(values->begin(), cachedValues.begin(), cachedValues.end());
}
else if (m_ecl_SmSpec)
{
const smspec_node_type* ertSumVarNode = ecl_smspec_iget_node(m_ecl_SmSpec, variableIndex);
int paramsIndex = smspec_node_get_params_index(ertSumVarNode);
@ -398,6 +403,8 @@ bool RifReaderEclipseSummary::values(const RifEclipseSummaryAddress& resultAddre
values->push_back(double_vector_iget(dataValues, i));
}
free(dataValues);
m_valuesCache->insertValues(resultAddress, *values);
}
}
@ -519,6 +526,22 @@ std::string RifReaderEclipseSummary::unitName(const RifEclipseSummaryAddress& re
return smspec_node_get_unit(ertSumVarNode);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseSummary::markForCachePurge(const RifEclipseSummaryAddress& address)
{
m_valuesCache->markAddressForPurge(address);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseSummary::purgeCache()
{
ValuesCache::purge();
}
#if 0
//--------------------------------------------------------------------------------------------------
///
@ -534,3 +557,76 @@ void RifReaderEclipseSummary::populateVectorFromStringList(stringlist_type* stri
}
#endif
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double> RifReaderEclipseSummary::ValuesCache::EMPTY_VECTOR;
std::set<RifReaderEclipseSummary::ValuesCache*> RifReaderEclipseSummary::ValuesCache::m_instances;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifReaderEclipseSummary::ValuesCache::ValuesCache()
{
// Register instance
m_instances.insert(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifReaderEclipseSummary::ValuesCache::~ValuesCache()
{
// Deregister instance
m_instances.erase(this);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseSummary::ValuesCache::insertValues(const RifEclipseSummaryAddress& address, const std::vector<double>& values)
{
m_cachedValues[address] = values;
m_purgeList.erase(address);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::vector<double>& RifReaderEclipseSummary::ValuesCache::getValues(const RifEclipseSummaryAddress& address) const
{
if (m_cachedValues.find(address) != m_cachedValues.end())
{
return m_cachedValues.at(address);
}
return EMPTY_VECTOR;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseSummary::ValuesCache::markAddressForPurge(const RifEclipseSummaryAddress& address)
{
m_purgeList.insert(address);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseSummary::ValuesCache::purge()
{
for (auto instance : m_instances) instance->purgeData();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseSummary::ValuesCache::purgeData()
{
for (const auto purgeAddr : m_purgeList)
{
m_cachedValues.erase(purgeAddr);
}
m_purgeList.clear();
}

View File

@ -27,6 +27,8 @@
#include <string>
#include <vector>
#include <map>
#include <set>
#include <memory>
//==================================================================================================
@ -68,6 +70,9 @@ public:
QStringList warnings() const { return m_warnings; }
virtual void markForCachePurge(const RifEclipseSummaryAddress& address) override;
static void purgeCache();
private:
int timeStepCount() const;
int indexFromAddress(const RifEclipseSummaryAddress& resultAddress) const;
@ -86,5 +91,33 @@ private:
std::map<RifEclipseSummaryAddress, int> m_resultAddressToErtNodeIdx;
QStringList m_warnings;
//==================================================================================================
//
//==================================================================================================
class ValuesCache
{
static const std::vector<double> EMPTY_VECTOR;
public:
ValuesCache();
~ValuesCache();
void insertValues(const RifEclipseSummaryAddress& address, const std::vector<double>& values);
const std::vector<double>& getValues(const RifEclipseSummaryAddress& address) const;
void markAddressForPurge(const RifEclipseSummaryAddress& address);
static void purge();
private:
void purgeData();
std::map<const RifEclipseSummaryAddress, std::vector<double>> m_cachedValues;
std::set<RifEclipseSummaryAddress> m_purgeList;
static std::set<ValuesCache*> m_instances;
};
std::unique_ptr<ValuesCache> m_valuesCache;
};

View File

@ -51,6 +51,8 @@ public:
// TODO: Move this to a tools class with static members
static std::vector<QDateTime> fromTimeT(const std::vector<time_t>& timeSteps);
virtual void markForCachePurge(const RifEclipseSummaryAddress& address) {}
protected:
std::set<RifEclipseSummaryAddress> m_allResultAddresses; // Result and error addresses
std::set<RifEclipseSummaryAddress> m_allErrorAddresses; // Error addresses

View File

@ -304,6 +304,7 @@ void RimEnsembleCurveSet::deleteCurve(RimSummaryCurve* curve)
if (curve)
{
m_curves.removeChildObject(curve);
curve->markCachedDataForPurge();
delete curve;
}
}
@ -1097,6 +1098,17 @@ void RimEnsembleCurveSet::showCurves(bool show)
m_showCurves = show;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveSet::markCachedDataForPurge()
{
for (const auto curve : m_curves)
{
curve->markCachedDataForPurge();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -104,6 +104,8 @@ public:
RimEnsembleCurveSet* clone() const;
void showCurves(bool show);
void markCachedDataForPurge();
void updateAllTextInPlot();
std::vector<QString> ensembleParameterNames() const;

View File

@ -160,11 +160,21 @@ void RimEnsembleCurveSetCollection::addCurveSet(RimEnsembleCurveSet* curveSet)
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveSetCollection::deleteCurveSet(RimEnsembleCurveSet* curveSet)
{
if (curveSet)
deleteCurveSets({ curveSet });
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveSetCollection::deleteCurveSets(const std::vector<RimEnsembleCurveSet*> curveSets)
{
for(const auto curveSet : curveSets)
{
m_curveSets.removeChildObject(curveSet);
curveSet->markCachedDataForPurge();
delete curveSet;
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -50,6 +50,7 @@ public:
void addCurveSet(RimEnsembleCurveSet* curveSet);
void deleteCurveSet(RimEnsembleCurveSet* curveSet);
void deleteCurveSets(const std::vector<RimEnsembleCurveSet*> curveSets);
std::vector<RimEnsembleCurveSet*> curveSets() const;
size_t curveSetCount() const;

View File

@ -53,6 +53,8 @@ RimSummaryCaseCollection::RimSummaryCaseCollection()
CAF_PDM_InitField(&m_isEnsemble, "IsEnsemble", false, "Is Ensemble", "", "", "");
m_isEnsemble.uiCapability()->setUiHidden(true);
m_commonAddressCount = 0;
}
//--------------------------------------------------------------------------------------------------
@ -182,6 +184,10 @@ std::set<RifEclipseSummaryAddress> RimSummaryCaseCollection::calculateUnionOfSum
const std::set<RifEclipseSummaryAddress>& readerAddresses = reader->allResultAddresses();
addressUnion.insert(readerAddresses.begin(), readerAddresses.end());
// We assume that all cases have the same addresses when they have equal number of addresses.
// In that case there is no need to calculate the union, we only use the addresses from the first case
if (m_commonAddressCount > 0) break;
}
return addressUnion;
}
@ -314,6 +320,27 @@ void RimSummaryCaseCollection::calculateEnsembleParametersIntersectionHash()
auto crp = sumCase->caseRealizationParameters();
if(crp) crp->calculateParametersHash(paramNames);
}
// Find common addess count
for (const auto sumCase : sumCases)
{
const auto reader = sumCase->summaryReader();
if(!reader) continue;
auto currAddrCount = reader->allResultAddresses().size();
if (m_commonAddressCount == 0)
{
m_commonAddressCount = currAddrCount;
}
else
{
if (currAddrCount != m_commonAddressCount)
{
m_commonAddressCount = 0;
break;
}
}
}
}
//--------------------------------------------------------------------------------------------------

View File

@ -100,5 +100,7 @@ protected:
private:
caf::PdmField<QString> m_name;
caf::PdmProxyValueField<QString> m_nameAndItemCount;
caf::PdmField<bool> m_isEnsemble;
caf::PdmField<bool> m_isEnsemble;
size_t m_commonAddressCount; // if different address count among cases, set to 0
};

View File

@ -738,6 +738,14 @@ void RimSummaryCurve::forceUpdateCurveAppearanceFromCaseType()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCurve::markCachedDataForPurge()
{
valuesSummaryReaderY()->markForCachePurge(m_yValuesCurveVariable->address());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -79,6 +79,8 @@ public:
virtual QString curveExportDescription(const RifEclipseSummaryAddress& address = RifEclipseSummaryAddress()) const override;
void forceUpdateCurveAppearanceFromCaseType();
void markCachedDataForPurge();
protected:
// RimPlotCurve overrides
virtual QString createCurveAutoName() override;

View File

@ -179,8 +179,8 @@ void RimSummaryCurveCollection::deleteCurve(RimSummaryCurve* curve)
if (curve)
{
m_curves.removeChildObject(curve);
curve->markCachedDataForPurge();
delete curve;
updateCaseNameHasChanged();
}
}

View File

@ -60,7 +60,7 @@
#include <set>
#include <limits>
#include <QDebug>
CAF_PDM_SOURCE_INIT(RimSummaryPlot, "SummaryPlot");
@ -953,7 +953,15 @@ void RimSummaryPlot::addCurveNoUpdate(RimSummaryCurve* curve)
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::deleteCurve(RimSummaryCurve* curve)
{
if (curve)
deleteCurves({ curve });
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryPlot::deleteCurves(const std::vector<RimSummaryCurve*>& curves)
{
for(const auto curve : curves)
{
if (m_summaryCurveCollection)
{
@ -962,7 +970,7 @@ void RimSummaryPlot::deleteCurve(RimSummaryCurve* curve)
if (c == curve)
{
m_summaryCurveCollection->deleteCurve(curve);
return;
continue;
}
}
}
@ -983,12 +991,13 @@ void RimSummaryPlot::deleteCurve(RimSummaryCurve* curve)
}
m_ensembleCurveSetCollection->deleteCurveSet(curveSet);
}
return;
continue;
}
}
}
}
}
updateCaseNameHasChanged();
}
//--------------------------------------------------------------------------------------------------

View File

@ -74,6 +74,8 @@ public:
void addCurveNoUpdate(RimSummaryCurve* curve);
void deleteCurve(RimSummaryCurve* curve);
void deleteCurves(const std::vector<RimSummaryCurve*>& curves);
void setCurveCollection(RimSummaryCurveCollection* curveCollection);
void deleteCurvesAssosiatedWithCase(RimSummaryCase* summaryCase);