diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp b/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp index 9bb0afa522..e76ed01dfe 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.cpp @@ -19,11 +19,15 @@ #include "RifStimPlanModelGeologicalFrkExporter.h" #include "RiaLogging.h" +#include "RiaPreferences.h" + +#include "RifCsvDataTableFormatter.h" #include "RimStimPlanModel.h" #include "RimStimPlanModelCalculator.h" #include +#include #include //-------------------------------------------------------------------------------------------------- @@ -126,6 +130,25 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToFile( RimStimPlanModel* stimP values["zonePoroElas"] = stimPlanModel->calculator()->calculatePoroElasticConstant(); values["zoneThermalExp"] = stimPlanModel->calculator()->calculateThermalExpansionCoefficient(); + // Special values for csv export + auto [depthStart, depthEnd] = createDepthRanges( tvd ); + values["dpthstart"] = depthStart; + values["dpthend"] = depthEnd; + std::vector csvLabels = { "dpthstart", "dpthend" }; + for ( const QString& label : labels ) + csvLabels.push_back( label ); + + return writeToFrkFile( filepath, labels, values ) && writeToCsvFile( filepath, csvLabels, values ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifStimPlanModelGeologicalFrkExporter::writeToFrkFile( const QString& filepath, + const std::vector& labels, + const std::map>& values ) + +{ QFile data( filepath ); if ( !data.open( QFile::WriteOnly | QFile::Truncate ) ) { @@ -137,8 +160,11 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToFile( RimStimPlanModel* stimP for ( QString label : labels ) { - warnOnInvalidData( label, values[label] ); - appendToStream( stream, label, values[label] ); + auto vals = values.find( label ); + if ( vals == values.end() ) return false; + + warnOnInvalidData( label, vals->second ); + appendToStream( stream, label, vals->second ); } appendFooterToStream( stream ); @@ -146,6 +172,63 @@ bool RifStimPlanModelGeologicalFrkExporter::writeToFile( RimStimPlanModel* stimP return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifStimPlanModelGeologicalFrkExporter::writeToCsvFile( const QString& filepath, + const std::vector& labels, + const std::map>& values ) + +{ + // Create the csv in the same directory as the frk file + QFileInfo fi( filepath ); + QString csvFilepath = fi.absolutePath() + "/Geological.csv"; + + QFile data( csvFilepath ); + if ( !data.open( QFile::WriteOnly | QFile::Truncate ) ) + { + return false; + } + + QTextStream stream( &data ); + QString fieldSeparator = RiaPreferences::current()->csvTextExportFieldSeparator; + RifCsvDataTableFormatter formatter( stream, fieldSeparator ); + + // Construct header + std::vector header; + for ( auto label : labels ) + { + header.push_back( RifTextDataTableColumn( label, RifTextDataTableDoubleFormat::RIF_FLOAT ) ); + } + formatter.header( header ); + + // The length of the vectors are assumed to be equal + size_t idx = 0; + bool isDone = false; + while ( !isDone ) + { + // Construct one row + for ( auto label : labels ) + { + auto vals = values.find( label ); + if ( vals == values.end() ) return false; + + if ( idx >= vals->second.size() ) + isDone = true; + else + { + formatter.add( vals->second[idx] ); + } + } + formatter.rowCompleted(); + idx++; + } + + formatter.tableCompleted(); + + return true; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -238,3 +321,25 @@ bool RifStimPlanModelGeologicalFrkExporter::hasInvalidData( const std::vector, std::vector> + RifStimPlanModelGeologicalFrkExporter::createDepthRanges( const std::vector& tvd ) +{ + std::vector startTvd; + std::vector endTvd; + + for ( size_t i = 0; i < tvd.size(); i++ ) + { + startTvd.push_back( tvd[i] ); + // Special handling for last range + if ( i == tvd.size() - 1 ) + endTvd.push_back( startTvd[i] ); + else + endTvd.push_back( tvd[i + 1] ); + } + + return std::make_pair( startTvd, endTvd ); +} diff --git a/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.h b/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.h index cfdea5f942..c1b0f7a9df 100644 --- a/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.h +++ b/ApplicationLibCode/FileInterface/RifStimPlanModelGeologicalFrkExporter.h @@ -18,6 +18,7 @@ #pragma once +#include #include class RimStimPlanModel; @@ -38,6 +39,13 @@ public: static bool writeToFile( RimStimPlanModel* plot, bool useDetailedFluidLoss, const QString& filepath ); private: + static bool writeToFrkFile( const QString& filepath, + const std::vector& labels, + const std::map>& values ); + static bool writeToCsvFile( const QString& filepath, + const std::vector& labels, + const std::map>& values ); + static void appendHeaderToStream( QTextStream& stream ); static void appendToStream( QTextStream& stream, const QString& label, const std::vector& values ); static void appendFooterToStream( QTextStream& stream ); @@ -47,6 +55,8 @@ private: double maxStressGradient, double defaultStressGradient ); + static std::pair, std::vector> createDepthRanges( const std::vector& tvd ); + static bool warnOnInvalidData( const QString& label, const std::vector& values ); static bool hasInvalidData( const std::vector& values ); };