///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2011- Statoil ASA // Copyright (C) 2013- Ceetron Solutions AS // Copyright (C) 2011-2012 Ceetron AS // // 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimProject.h" #include "RiaCompletionTypeCalculationScheduler.h" #include "RiaFieldHandleTools.h" #include "RiaFilePathTools.h" #include "RiaGuiApplication.h" #include "RiaPreferences.h" #include "RiaPreferencesSystem.h" #include "RiaProjectBackupTools.h" #include "RiaProjectFileTools.h" #include "RiaVersionInfo.h" #include "RigEclipseCaseData.h" #include "Cloud/RimCloudDataSourceCollection.h" #include "ContourMap/RimEclipseContourMapViewCollection.h" #include "EnsembleFileSet/RimEnsembleFileSetCollection.h" #include "Formations/RimFormationNamesCollection.h" #include "Formations/RimWellFormationsCollection.h" #include "Jobs/RimJobCollection.h" #include "PlotTemplates/RimPlotTemplateFolderItem.h" #include "Polygons/RimPolygonCollection.h" #include "QuickAccess/RimQuickAccessCollection.h" #include "RimAdvancedSnapshotExportDefinition.h" #include "RimAnalysisPlotCollection.h" #include "RimAnnotationCollection.h" #include "RimAnnotationInViewCollection.h" #include "RimCase.h" #include "RimCaseCollection.h" #include "RimColorLegendCollection.h" #include "RimCompletionTemplateCollection.h" #include "RimContextCommandBuilder.h" #include "RimCorrelationPlotCollection.h" #include "RimDialogData.h" #include "RimEclipseCase.h" #include "RimEclipseCaseCollection.h" #include "RimEclipseCaseEnsemble.h" #include "RimEclipseView.h" #include "RimEnsembleWellLogsCollection.h" #include "RimFlowPlotCollection.h" #include "RimFractureTemplate.h" #include "RimFractureTemplateCollection.h" #include "RimGeneric3dView.h" #include "RimGenericViewCollection.h" #include "RimGeoMechCase.h" #include "RimGeoMechModels.h" #include "RimGridCalculationCollection.h" #include "RimGridCrossPlotCollection.h" #include "RimGridView.h" #include "RimIdenticalGridCaseGroup.h" #include "RimMainPlotCollection.h" #include "RimMeasurement.h" #include "RimMultiPlotCollection.h" #include "RimObservedDataCollection.h" #include "RimObservedSummaryData.h" #include "RimOilField.h" #include "RimPlotWindow.h" #include "RimPltPlotCollection.h" #include "RimPolylinesFromFileAnnotation.h" #include "RimReservoirGridEnsemble.h" #include "RimRftPlotCollection.h" #include "RimSaturationPressurePlotCollection.h" #include "RimScriptCollection.h" #include "RimSeismicDataCollection.h" #include "RimSeismicView.h" #include "RimSeismicViewCollection.h" #include "RimStimPlanModelPlotCollection.h" #include "RimSummaryCalculationCollection.h" #include "RimSummaryCase.h" #include "RimSummaryCaseMainCollection.h" #include "RimSummaryEnsemble.h" #include "RimSummaryMultiPlotCollection.h" #include "RimSummaryTableCollection.h" #include "RimSurfaceCollection.h" #include "RimTools.h" #include "RimValveTemplate.h" #include "RimValveTemplateCollection.h" #include "RimViewLinker.h" #include "RimViewLinkerCollection.h" #include "RimWellLogPlotCollection.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" #include "RimWellTargetMapping.h" #include "Summary/RimCurveStyleRules.h" #include "Tools/RimAutomationSettings.h" #include "VerticalFlowPerformance/RimVfpDataCollection.h" #include "VerticalFlowPerformance/RimVfpPlotCollection.h" #include "Workflow/RimWorkflowCollection.h" #include "RiuPlotMainWindow.h" #include "cafCmdFeatureMenuBuilder.h" #include "cafPdmObjectScriptingCapability.h" #include "cafPdmUiTreeOrdering.h" #include #include #include CAF_PDM_SOURCE_INIT( RimProject, "ResInsightProject" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimProject::RimProject() { CAF_PDM_InitScriptableObjectWithNameAndComment( "Project", "", "", "", "Project", "The ResInsight Project" ); CAF_PDM_InitField( &m_projectFileVersionString, "ProjectFileVersionString", QString( STRPRODUCTVER ), "" ); m_projectFileVersionString.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &m_globalPathList, "ReferencedExternalFiles", "" ); m_globalPathList.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &oilFields, "OilFields", "Oil Fields" ); CAF_PDM_InitFieldNoDefault( &colorLegendCollection, "ColorLegendCollection", "Color Legend Collection" ); colorLegendCollection = new RimColorLegendCollection(); colorLegendCollection->createStandardColorLegends(); CAF_PDM_InitFieldNoDefault( &scriptCollection, "ScriptCollection", "Octave Scripts", ":/octave.png" ); scriptCollection.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &workflowCollection, "WorkflowCollection", "Workflows", ":/Folder.png" ); workflowCollection.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &m_jobCollection, "JobCollection", "Jobs", ":/gear.png" ); CAF_PDM_InitFieldNoDefault( &m_mainPlotCollection, "MainPlotCollection", "Plots" ); CAF_PDM_InitFieldNoDefault( &m_pinnedFieldCollection, "PinnedFieldCollection", "PinnedFieldCollection" ); CAF_PDM_InitFieldNoDefault( &m_curveStyleRules, "CurveStyleRules", "Curve Style Rules" ); m_curveStyleRules = new RimCurveStyleRules; CAF_PDM_InitFieldNoDefault( &viewLinkerCollection, "LinkedViews", "Linked Views", ":/LinkView.svg" ); viewLinkerCollection = new RimViewLinkerCollection; CAF_PDM_InitFieldNoDefault( &calculationCollection, "CalculationCollection", "Calculation Collection" ); calculationCollection = new RimSummaryCalculationCollection; CAF_PDM_InitFieldNoDefault( &gridCalculationCollection, "GridCalculationCollection", "Grid Calculation Collection" ); gridCalculationCollection = new RimGridCalculationCollection; CAF_PDM_InitFieldNoDefault( &multiSnapshotDefinitions, "MultiSnapshotDefinitions", "Multi Snapshot Definitions" ); CAF_PDM_InitFieldNoDefault( &mainWindowTreeViewStates, "TreeViewStates", "" ); mainWindowTreeViewStates.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &mainWindowCurrentModelIndexPaths, "TreeViewCurrentModelIndexPaths", "" ); mainWindowCurrentModelIndexPaths.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &plotWindowTreeViewStates, "PlotWindowTreeViewStates", "" ); plotWindowTreeViewStates.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &plotWindowCurrentModelIndexPaths, "PlotWindowTreeViewCurrentModelIndexPaths", "" ); plotWindowCurrentModelIndexPaths.uiCapability()->setUiHidden( true ); CAF_PDM_InitField( &m_show3DWindow, "show3DWindow", true, "Show 3D Window" ); m_show3DWindow.uiCapability()->setUiHidden( true ); CAF_PDM_InitField( &m_showPlotWindow, "showPlotWindow", false, "Show Plot Window" ); m_showPlotWindow.uiCapability()->setUiHidden( true ); CAF_PDM_InitField( &m_showPlotWindowOnTopOf3DWindow, "showPlotWindowOnTopOf3DWindow", false, "Show Plot On Top" ); m_showPlotWindowOnTopOf3DWindow.uiCapability()->setUiHidden( true ); CAF_PDM_InitField( &mainWindowDockState, "MainWindowDockState", QString(), "Dock State 3D Window" ); mainWindowDockState.uiCapability()->setUiHidden( true ); CAF_PDM_InitField( &plotWindowDockState, "PlotWindowDockState", QString(), "Dock State Plot Window" ); plotWindowDockState.uiCapability()->setUiHidden( true ); CAF_PDM_InitFieldNoDefault( &m_dialogData, "DialogData", "DialogData" ); m_dialogData = new RimDialogData(); m_dialogData.uiCapability()->setUiTreeChildrenHidden( true ); // Obsolete fields. The content is moved to OilFields and friends CAF_PDM_InitFieldNoDefault( &casesObsolete, "Reservoirs", "" ); RiaFieldHandleTools::disableWriteAndSetFieldHidden( &casesObsolete ); CAF_PDM_InitFieldNoDefault( &caseGroupsObsolete, "CaseGroups", "" ); RiaFieldHandleTools::disableWriteAndSetFieldHidden( &caseGroupsObsolete ); // Initialization scriptCollection = new RimScriptCollection(); scriptCollection->directory.uiCapability()->setUiHidden( true ); scriptCollection->uiCapability()->setUiName( "Scripts" ); scriptCollection->uiCapability()->setUiIconFromResourceString( ":/octave.png" ); workflowCollection = new RimWorkflowCollection(); workflowCollection->uiCapability()->setUiName( "Workflows" ); m_mainPlotCollection = new RimMainPlotCollection(); m_pinnedFieldCollection = new RimQuickAccessCollection(); m_jobCollection = new RimJobCollection(); CAF_PDM_InitFieldNoDefault( &m_plotTemplateTopFolder, "PlotTemplateCollection", "Plot Templates" ); m_plotTemplateTopFolder = new RimPlotTemplateFolderItem(); m_plotTemplateTopFolder.xmlCapability()->disableIO(); CAF_PDM_InitFieldNoDefault( &m_automationSettings, "AutomationSettings", "Automation Settings" ); m_automationSettings = new RimAutomationSettings(); CAF_PDM_InitFieldNoDefault( &m_ensembleFileSetCollection, "EnsembleFileSetCollection", "Ensemble File Sets" ); m_ensembleFileSetCollection = new RimEnsembleFileSetCollection(); // For now, create a default first oilfield that contains the rest of the project oilFields.push_back( new RimOilField ); setUiHidden( true ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimProject::~RimProject() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimProject* RimProject::current() { return RiaApplication::instance()->project(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::close() { if ( m_mainPlotCollection() ) { m_mainPlotCollection()->deleteAllContainedObjects(); } m_jobCollection->deleteAllJobs(); m_ensembleFileSetCollection()->deleteAllFileSets(); oilFields.deleteChildren(); oilFields.push_back( new RimOilField ); casesObsolete.deleteChildren(); caseGroupsObsolete.deleteChildren(); multiSnapshotDefinitions.deleteChildren(); m_dialogData->clearProjectSpecificData(); calculationCollection->deleteAllContainedObjects(); gridCalculationCollection->deleteAllContainedObjects(); colorLegendCollection->deleteCustomColorLegends(); delete viewLinkerCollection->viewLinker(); viewLinkerCollection->viewLinker = nullptr; setFileName( "" ); m_globalPathList = ""; mainWindowCurrentModelIndexPaths = ""; mainWindowTreeViewStates = ""; plotWindowCurrentModelIndexPaths = ""; plotWindowTreeViewStates = ""; mainWindowDockState = ""; plotWindowDockState = ""; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::updatesAfterProjectFileIsRead() { RiaProjectFileTools::distributePathsFromGlobalPathList( this, m_globalPathList() ); // Create an empty oil field in case the project did not contain one if ( oilFields.empty() ) { oilFields.push_back( new RimOilField ); } // Handle old project files with obsolete structure. // Move caseGroupsObsolete and casesObsolete to oilFields()[idx]->analysisModels() RimEclipseCaseCollection* analysisModels = activeOilField() ? activeOilField()->analysisModels() : nullptr; bool movedOneRimIdenticalGridCaseGroup = false; for ( size_t cgIdx = 0; cgIdx < caseGroupsObsolete.size(); ++cgIdx ) { RimIdenticalGridCaseGroup* sourceCaseGroup = caseGroupsObsolete[cgIdx]; if ( analysisModels ) { analysisModels->caseGroups.push_back( sourceCaseGroup ); movedOneRimIdenticalGridCaseGroup = true; // moved at least one so assume the others will be moved too... } } if ( movedOneRimIdenticalGridCaseGroup ) { caseGroupsObsolete.clearWithoutDelete(); } bool movedOneRimCase = false; for ( size_t cIdx = 0; cIdx < casesObsolete().size(); ++cIdx ) { if ( analysisModels ) { RimEclipseCase* sourceCase = casesObsolete[cIdx]; casesObsolete.set( cIdx, nullptr ); analysisModels->cases.push_back( sourceCase ); movedOneRimCase = true; // moved at least one so assume the others will be moved too... } } if ( movedOneRimCase ) { casesObsolete.clearWithoutDelete(); } // Set project pointer to each well path for ( size_t oilFieldIdx = 0; oilFieldIdx < oilFields().size(); oilFieldIdx++ ) { RimOilField* oilField = oilFields[oilFieldIdx]; if ( oilField == nullptr || oilField->wellPathCollection == nullptr ) continue; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimQuickAccessCollection* RimProject::pinnedFieldCollection() const { return m_pinnedFieldCollection(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCurveStyleRules* RimProject::curveStyleRules() const { return m_curveStyleRules(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimJobCollection* RimProject::jobCollection() const { return m_jobCollection(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimAutomationSettings* RimProject::automationSettings() const { return m_automationSettings(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimEnsembleFileSetCollection* RimProject::ensembleFileSetCollection() const { return m_ensembleFileSetCollection(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::initAfterRead() { // Function moved to beforeInitAfterRead() to make sure that file path objects are replaced before other initAfterRead() is called } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::setupBeforeSave() { if ( RiaGuiApplication::isRunning() ) { RiaGuiApplication* guiApp = RiaGuiApplication::instance(); if ( guiApp ) { m_show3DWindow = guiApp->isMain3dWindowVisible(); m_showPlotWindow = guiApp->isMainPlotWindowVisible(); if ( m_showPlotWindow ) { auto plotWindow = RiuPlotMainWindow::instance(); m_showPlotWindowOnTopOf3DWindow = plotWindow->isTopLevel(); } } } m_projectFileVersionString = STRPRODUCTVER; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::fieldsForExport() const { std::vector orderedKeywords; orderedKeywords.push_back( fileNameHandle()->keyword() ); orderedKeywords.push_back( m_projectFileVersionString.keyword() ); orderedKeywords.push_back( m_globalPathList.keyword() ); orderedKeywords.push_back( m_ensembleFileSetCollection.keyword() ); std::vector ordered; auto fieldHandles = fields(); for ( const auto& kw : orderedKeywords ) { auto it = std::find_if( fieldHandles.begin(), fieldHandles.end(), [&]( const caf::PdmFieldHandle* field ) { return field->keyword() == kw; } ); if ( it != fieldHandles.end() ) { ordered.push_back( *it ); } } // Append the rest of the fields for ( auto fieldHandle : fields() ) { if ( std::find( ordered.begin(), ordered.end(), fieldHandle ) == ordered.end() ) { ordered.push_back( fieldHandle ); } } return ordered; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimMainPlotCollection* RimProject::mainPlotCollection() const { return m_mainPlotCollection(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimProject::writeProjectFile() { m_globalPathList = RiaProjectFileTools::transferPathsToGlobalPathList( this ); QFile xmlFile( fileName() ); if ( !xmlFile.open( QIODevice::WriteOnly | QIODevice::Text ) ) return false; QString content = documentAsString(); xmlFile.write( content.toUtf8() ); if ( RiaPreferences::current()->storeBackupOfProjectFiles() ) { QString backupFilename = fileName() + "db"; const int maximumRecordCount = 50; RiaProjectBackupTools::appendTextToDatabase( backupFilename, maximumRecordCount, content ); } RiaProjectFileTools::distributePathsFromGlobalPathList( this, m_globalPathList() ); return true; } //-------------------------------------------------------------------------------------------------- /// Support list of multiple script paths divided by ';' //-------------------------------------------------------------------------------------------------- void RimProject::setScriptDirectories( const QString& scriptDirectories, int maxFolderDepth ) { scriptCollection->calcScripts().deleteChildren(); scriptCollection->subDirectories().deleteChildren(); QStringList pathList = scriptDirectories.split( ';' ); for ( const QString& path : pathList ) { QDir dir( path ); if ( !path.isEmpty() && dir.exists() && dir.isReadable() ) { RimScriptCollection* sharedScriptLocation = new RimScriptCollection; sharedScriptLocation->directory = path; sharedScriptLocation->setUiName( dir.dirName() ); sharedScriptLocation->readContentFromDisc( maxFolderDepth ); scriptCollection->subDirectories.push_back( sharedScriptLocation ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::setPlotTemplateFolders( const QStringList& plotTemplateFolders ) { if ( !m_plotTemplateTopFolder() ) { m_plotTemplateTopFolder = new RimPlotTemplateFolderItem(); } m_plotTemplateTopFolder->createRootFolderItemsFromFolderPaths( plotTemplateFolders ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RimProject::projectFileVersionString() const { return m_projectFileVersionString; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimProject::isProjectFileVersionEqualOrOlderThan( const QString& otherProjectFileVersion ) const { QString candidateProjectFileVersion = projectFileVersionString(); return !RiaProjectFileTools::isCandidateVersionNewerThanOther( candidateProjectFileVersion, otherProjectFileVersion ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::setProjectFileNameAndUpdateDependencies( const QString& projectFileName ) { // Extract the filename of the project file when it was saved QString oldProjectFileName = fileName(); // Replace with the new actual filename setFileName( projectFileName ); QFileInfo fileInfo( projectFileName ); QString newProjectPath = fileInfo.path(); QFileInfo fileInfoOld( oldProjectFileName ); QString oldProjectPath = fileInfoOld.path(); if ( newProjectPath == oldProjectPath ) return; for ( caf::FilePath* filePath : allFilePaths() ) { QString filePathCandidate = filePath->path(); QString newFilePath = RimTools::relocateFile( filePathCandidate, newProjectPath, oldProjectPath ); filePath->setPath( newFilePath ); } if ( ensembleFileSetCollection() ) ensembleFileSetCollection()->updateFilePathsFromProjectPath( newProjectPath, oldProjectPath ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::assignCaseIdToSummaryCase( RimSummaryCase* summaryCase ) { assignCaseIdsToSummaryCases( { summaryCase } ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::assignCaseIdsToSummaryCases( const std::vector& summaryCases ) { int nextValidId = 1; for ( RimSummaryCase* s : allSummaryCases() ) { nextValidId = std::max( nextValidId, s->caseId() + 1 ); } for ( RimSummaryCase* summaryCase : summaryCases ) { if ( summaryCase ) summaryCase->setCaseId( nextValidId++ ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::assignIdToEnsemble( RimSummaryEnsemble* summaryCaseCollection ) { if ( summaryCaseCollection ) { int nextValidId = 1; for ( RimSummaryEnsemble* ensemble : summaryEnsembles() ) { nextValidId = std::max( nextValidId, ensemble->ensembleId() + 1 ); } summaryCaseCollection->setEnsembleId( nextValidId ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allGridCases() const { std::vector cases; for ( RimOilField* oilField : oilFields() ) { if ( !oilField ) continue; RimEclipseCaseCollection* analysisModels = oilField->analysisModels(); if ( analysisModels ) { for ( RimEclipseCase* eclipseCase : analysisModels->cases ) { cases.push_back( eclipseCase ); } for ( RimIdenticalGridCaseGroup* cg : analysisModels->caseGroups ) { // Load the Main case of each IdenticalGridCaseGroup if ( cg == nullptr ) continue; if ( cg->statisticsCaseCollection() ) { for ( RimEclipseCase* eclipseCase : cg->statisticsCaseCollection()->reservoirs ) { cases.push_back( eclipseCase ); } } if ( cg->caseCollection() ) { for ( RimEclipseCase* eclipseCase : cg->caseCollection()->reservoirs ) { cases.push_back( eclipseCase ); } } } for ( RimEclipseCaseEnsemble* ensemble : analysisModels->caseEnsembles() ) { // The ensemble can be null if this function is called while the ensembles are being deleted, // as PdmPointer entries in the child array field are nulled one by one during deletion. if ( ensemble == nullptr ) continue; for ( RimEclipseCase* acase : ensemble->cases() ) { cases.push_back( acase ); } for ( RimWellTargetMapping* wellTargetMapping : ensemble->wellTargetMappings() ) { if ( auto ensembleStatisticsCase = wellTargetMapping->ensembleStatisticsCase() ) cases.push_back( ensembleStatisticsCase ); } } for ( RimReservoirGridEnsemble* ensemble : analysisModels->reservoirGridEnsembles.childrenByType() ) { if ( ensemble == nullptr ) continue; for ( RimEclipseCase* acase : ensemble->cases() ) { cases.push_back( acase ); } if ( ensemble->statisticsCaseCollection() ) { for ( RimEclipseCase* eclipseCase : ensemble->statisticsCaseCollection()->reservoirs ) { cases.push_back( eclipseCase ); } } } RimGeoMechModels* geomModels = oilField->geoMechModels(); if ( geomModels ) { for ( auto acase : geomModels->cases() ) { cases.push_back( acase ); } } } } return cases; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::assignCaseIdToCase( RimCase* reservoirCase ) { if ( reservoirCase ) { int nextValidId = 0; for ( RimCase* rimCase : descendantsIncludingThisOfType() ) { nextValidId = std::max( nextValidId, rimCase->caseId() + 1 ); } reservoirCase->setCaseId( nextValidId ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::assignIdToCaseGroup( RimIdenticalGridCaseGroup* caseGroup ) { if ( caseGroup ) { int nextValidId = 0; for ( RimIdenticalGridCaseGroup* existingCaseGroup : descendantsIncludingThisOfType() ) { nextValidId = std::max( nextValidId, existingCaseGroup->groupId() + 1 ); } caseGroup->groupId = nextValidId; } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::assignIdToCaseGroup( RimReservoirGridEnsemble* gridEnsemble ) { if ( gridEnsemble ) { int nextValidId = 0; for ( RimIdenticalGridCaseGroup* existingCaseGroup : descendantsIncludingThisOfType() ) { nextValidId = std::max( nextValidId, existingCaseGroup->groupId() + 1 ); } for ( RimReservoirGridEnsemble* existingEnsemble : descendantsIncludingThisOfType() ) { nextValidId = std::max( nextValidId, existingEnsemble->groupId() + 1 ); } gridEnsemble->setGroupId( nextValidId ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::assignViewIdToView( Rim3dView* view ) { if ( view ) { int nextValidId = 0; for ( Rim3dView* existingView : descendantsIncludingThisOfType() ) { nextValidId = std::max( nextValidId, existingView->id() + 1 ); } view->setId( nextValidId ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::assignPlotIdToPlotWindow( RimPlotWindow* plotWindow ) { if ( plotWindow ) { int nextValidId = 0; for ( RimPlotWindow* existingPlotWindow : descendantsIncludingThisOfType() ) { nextValidId = std::max( nextValidId, existingPlotWindow->id() + 1 ); } plotWindow->setId( nextValidId ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allSummaryCases() const { std::vector sumCases; for ( RimOilField* oilField : oilFields ) { if ( !oilField ) continue; RimSummaryCaseMainCollection* sumCaseMainColl = oilField->summaryCaseMainCollection(); if ( sumCaseMainColl ) { std::vector allSummaryCases = sumCaseMainColl->allSummaryCases(); if ( !allSummaryCases.empty() ) { sumCases.insert( sumCases.end(), allSummaryCases.begin(), allSummaryCases.end() ); } } auto& observedDataColl = oilField->observedDataCollection(); if ( observedDataColl != nullptr && !observedDataColl->allObservedSummaryData().empty() ) { auto observedData = observedDataColl->allObservedSummaryData(); sumCases.insert( sumCases.end(), observedData.begin(), observedData.end() ); } } return sumCases; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::summaryEnsembles() const { std::vector ensembles; for ( RimOilField* oilField : oilFields ) { if ( !oilField ) continue; RimSummaryCaseMainCollection* sumCaseMainColl = oilField->summaryCaseMainCollection(); if ( sumCaseMainColl ) { std::vector ensemble = sumCaseMainColl->summaryEnsembles(); ensembles.insert( ensembles.end(), ensemble.begin(), ensemble.end() ); } } return ensembles; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allNotLinkedViews() const { std::vector alreadyLinkedViews; if ( viewLinkerCollection->viewLinker() ) { alreadyLinkedViews = viewLinkerCollection->viewLinker()->allViews(); } std::vector views; for ( RimCase* rimCase : allGridCases() ) { if ( !rimCase ) continue; for ( Rim3dView* caseView : rimCase->views() ) { RimGridView* gridView = dynamic_cast( caseView ); if ( !gridView ) continue; bool isLinked = false; for ( size_t lnIdx = 0; lnIdx < alreadyLinkedViews.size(); lnIdx++ ) { if ( gridView == alreadyLinkedViews[lnIdx] ) { isLinked = true; } } if ( !isLinked ) { views.push_back( gridView ); } } } return views; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allViews() const { std::vector views; for ( RimCase* rimCase : allGridCases() ) { if ( !rimCase ) continue; for ( Rim3dView* view : rimCase->views() ) { if ( view ) { views.push_back( view ); } } } for ( RimOilField* oilField : oilFields() ) { if ( !oilField ) continue; if ( oilField->seismicViewCollection() ) { for ( auto seisview : oilField->seismicViewCollection()->views() ) { views.push_back( seisview ); } } if ( oilField->genericViewCollection() ) { for ( auto dataView : oilField->genericViewCollection()->genericViews() ) { views.push_back( dataView ); } } if ( oilField->analysisModels() ) { for ( auto ensemble : oilField->analysisModels()->caseEnsembles.childrenByType() ) { if ( !ensemble ) continue; for ( auto view : ensemble->allViews() ) { views.push_back( view ); } } for ( auto gridEnsemble : oilField->analysisModels()->reservoirGridEnsembles.childrenByType() ) { if ( !gridEnsemble ) continue; for ( auto view : gridEnsemble->allViews() ) { views.push_back( view ); } } } } return views; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allVisibleViews() const { std::vector views; for ( auto view : allViews() ) { if ( view && view->viewer() ) { views.push_back( view ); } } return views; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allVisibleGridViews() const { std::vector views; for ( Rim3dView* view : allVisibleViews() ) { RimGridView* gridView = dynamic_cast( view ); if ( gridView ) views.push_back( gridView ); } return views; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::scheduleCreateDisplayModelAndRedrawAllViews() { for ( auto view : allViews() ) { if ( view ) view->scheduleCreateDisplayModelAndRedraw(); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allOilFields() const { return oilFields.childrenByType(); } //-------------------------------------------------------------------------------------------------- /// Currently there will be only one oil field in Resinsight, so return hardcoded first oil field /// from the RimOilField collection. //-------------------------------------------------------------------------------------------------- RimOilField* RimProject::activeOilField() { CAF_ASSERT( oilFields.size() == 1 ); return oilFields[0]; } //-------------------------------------------------------------------------------------------------- /// Currently there will be only one oil field in Resinsight, so return hardcoded first oil field /// from the RimOilField collection. //-------------------------------------------------------------------------------------------------- const RimOilField* RimProject::activeOilField() const { CAF_ASSERT( oilFields.size() == 1 ); return oilFields[0]; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::actionsBasedOnSelection( QMenu& contextMenu ) { caf::CmdFeatureMenuBuilder menuBuilder = RimContextCommandBuilder::commandsFromSelection(); menuBuilder.appendToMenu( &contextMenu ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimProject::show3DWindow() const { return m_show3DWindow; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimProject::showPlotWindow() const { return m_showPlotWindow; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RimProject::showPlotWindowOnTop() const { return m_showPlotWindowOnTopOf3DWindow(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::reloadCompletionTypeResultsInAllViews() { RiaCompletionTypeCalculationScheduler::instance()->clearCompletionTypeResultsInAllCases(); scheduleCreateDisplayModelAndRedrawAllViews(); m_mainPlotCollection()->scheduleUpdatePlotsWithCompletions(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimDialogData* RimProject::dialogData() const { return m_dialogData; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::eclipseCases() const { std::vector allGridCases; for ( const auto& oilField : oilFields ) { const auto& cases = oilField->analysisModels->cases; allGridCases.insert( allGridCases.end(), cases.begin(), cases.end() ); } return allGridCases; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimEclipseCase* RimProject::eclipseCaseFromGridFileName( const QString& gridFileName ) const { for ( RimEclipseCase* eclCase : eclipseCases() ) { if ( RiaFilePathTools::toInternalSeparator( eclCase->gridFileName() ) == RiaFilePathTools::toInternalSeparator( gridFileName ) ) { return eclCase; } } return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimEclipseCase* RimProject::eclipseCaseFromCaseId( const int caseId ) const { for ( RimEclipseCase* eclCase : eclipseCases() ) { if ( eclCase->caseId() == caseId ) { return eclCase; } } return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::simulationWellNames() const { std::set wellNames; for ( RimOilField* oilField : oilFields ) { auto analysisCaseColl = oilField->analysisModels(); for ( RimEclipseCase* eclCase : analysisCaseColl->cases() ) { const auto& eclData = eclCase->eclipseCaseData(); if ( eclData == nullptr ) continue; const auto names = eclData->simulationWellNames(); wellNames.insert( names.begin(), names.end() ); } } return std::vector( wellNames.begin(), wellNames.end() ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimWellPath* RimProject::wellPathFromSimWellName( const QString& simWellName, int branchIndex ) { for ( RimWellPath* const path : allWellPaths() ) { if ( QString::compare( path->associatedSimulationWellName(), simWellName ) == 0 && ( branchIndex < 0 || path->associatedSimulationWellBranch() == branchIndex ) ) { return path; } } for ( RimWellPath* const path : allWellPaths() ) { if ( QString::compare( path->name(), simWellName ) == 0 ) { return path; } } return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimWellPath* RimProject::wellPathByName( const QString& wellPathName ) const { for ( RimWellPath* const path : allWellPaths() ) { if ( path->name() == wellPathName ) return path; } return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allWellPaths() const { std::vector wellPaths; for ( const auto& oilField : oilFields() ) { auto wellPathColl = oilField->wellPathCollection(); for ( auto wellPath : wellPathColl->allWellPaths() ) { wellPaths.push_back( wellPath ); } } return wellPaths; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::textAnnotations() const { std::vector annotations; // 'Global' text annotations for ( const auto& oilField : oilFields() ) { auto annotationColl = oilField->annotationCollection(); for ( const auto& annotation : annotationColl->textAnnotations() ) { annotations.push_back( annotation ); } } // 'Local' text annotations for ( const auto& view : allVisibleGridViews() ) { std::vector annotationColls = view->descendantsIncludingThisOfType(); if ( annotationColls.size() == 1 ) { for ( const auto& annotation : annotationColls.front()->textAnnotations() ) { annotations.push_back( annotation ); } } } return annotations; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::reachCircleAnnotations() const { std::vector annotations; for ( const auto& oilField : oilFields() ) { auto annotationColl = oilField->annotationCollection(); for ( const auto& annotation : annotationColl->reachCircleAnnotations() ) { annotations.push_back( annotation ); } } return annotations; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::geoMechCases() const { std::vector cases; for ( RimOilField* oilField : oilFields() ) { if ( !oilField ) continue; RimGeoMechModels* geomModels = oilField->geoMechModels(); if ( geomModels ) { for ( auto acase : geomModels->cases() ) { cases.push_back( acase ); } } } return cases; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allFractureTemplateCollections() const { std::vector templColls; for ( RimOilField* oilField : allOilFields() ) { templColls.push_back( oilField->fractureDefinitionCollection() ); } return templColls; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allFractureTemplates() const { std::vector templates; for ( RimFractureTemplateCollection* templColl : allFractureTemplateCollections() ) { for ( RimFractureTemplate* templ : templColl->fractureTemplates() ) { templates.push_back( templ ); } } return templates; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allValveTemplateCollections() const { std::vector templColls; for ( RimOilField* oilField : allOilFields() ) { templColls.push_back( oilField->valveTemplateCollection() ); } return templColls; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allValveTemplates() const { std::vector templates; for ( RimValveTemplateCollection* templColl : allValveTemplateCollections() ) { for ( RimValveTemplate* templ : templColl->items() ) { templates.push_back( templ ); } } return templates; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- caf::AppEnum RimProject::commonUnitSystemForAllCases() const { RiaDefines::EclipseUnitSystem commonUnitSystem = RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN; for ( const auto& c : allGridCases() ) { auto eclipseCase = dynamic_cast( c ); if ( eclipseCase && eclipseCase->eclipseCaseData() ) { if ( commonUnitSystem == RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN ) { commonUnitSystem = eclipseCase->eclipseCaseData()->unitsType(); } else if ( commonUnitSystem != eclipseCase->eclipseCaseData()->unitsType() ) { commonUnitSystem = RiaDefines::EclipseUnitSystem::UNITS_UNKNOWN; break; } } } return commonUnitSystem; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimMeasurement* RimProject::measurement() const { return activeOilField()->measurement; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimPlotTemplateFolderItem* RimProject::rootPlotTemplateItem() const { return m_plotTemplateTopFolder; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimProject::allFilePaths() const { std::vector filePaths = RiaProjectFileTools::writableFieldContent( this ); return filePaths; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::reloadCompletionTypeResultsForEclipseCase( RimEclipseCase* eclipseCase ) { for ( Rim3dView* view : eclipseCase->views() ) { view->scheduleCreateDisplayModelAndRedraw(); } RiaCompletionTypeCalculationScheduler::instance()->scheduleRecalculateCompletionTypeAndRedrawAllViews( { eclipseCase } ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimProject::defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /*= ""*/ ) { if ( uiConfigName == "PlotWindow.Plots" ) { if ( m_mainPlotCollection ) { if ( m_mainPlotCollection->summaryMultiPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->summaryMultiPlotCollection() ); } if ( m_mainPlotCollection->analysisPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->analysisPlotCollection() ); } if ( m_mainPlotCollection->correlationPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->correlationPlotCollection() ); } if ( m_mainPlotCollection->summaryTableCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->summaryTableCollection() ); } if ( m_mainPlotCollection->wellLogPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->wellLogPlotCollection() ); } if ( m_mainPlotCollection->rftPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->rftPlotCollection() ); } if ( m_mainPlotCollection->pltPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->pltPlotCollection() ); } if ( m_mainPlotCollection->flowPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->flowPlotCollection() ); } if ( m_mainPlotCollection->gridCrossPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->gridCrossPlotCollection() ); } if ( m_mainPlotCollection->saturationPressurePlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->saturationPressurePlotCollection() ); } if ( m_mainPlotCollection->multiPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->multiPlotCollection() ); } if ( m_mainPlotCollection->stimPlanModelPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->stimPlanModelPlotCollection() ); } if ( m_mainPlotCollection->vfpPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->vfpPlotCollection() ); } if ( m_mainPlotCollection->histogramMultiPlotCollection() ) { uiTreeOrdering.add( m_mainPlotCollection->histogramMultiPlotCollection() ); } uiTreeOrdering.add( automationSettings() ); } } else if ( uiConfigName == "PlotWindow.DataSources" ) { RimOilField* oilField = activeOilField(); if ( oilField ) { if ( oilField->summaryCaseMainCollection() ) { uiTreeOrdering.add( oilField->summaryCaseMainCollection() ); } if ( oilField->observedDataCollection() ) { uiTreeOrdering.add( oilField->observedDataCollection() ); } if ( oilField->ensembleWellLogsCollection() ) { uiTreeOrdering.add( oilField->ensembleWellLogsCollection() ); } if ( oilField->vfpDataCollection() ) { uiTreeOrdering.add( oilField->vfpDataCollection() ); } if ( oilField->wellFormationsCollection() ) { uiTreeOrdering.add( oilField->wellFormationsCollection() ); } } } else if ( uiConfigName == "PlotWindow.Scripts" || uiConfigName == "MainWindow.Scripts" ) { uiTreeOrdering.add( scriptCollection() ); uiTreeOrdering.add( jobCollection() ); if ( RiaPreferencesSystem::current()->isFeatureEnabled( "workflows" ) ) { uiTreeOrdering.add( workflowCollection() ); } } else if ( uiConfigName == "PlotWindow.Templates" ) { uiTreeOrdering.add( m_plotTemplateTopFolder ); } else if ( uiConfigName == "PlotWindow.Cloud" ) { uiTreeOrdering.add( &m_ensembleFileSetCollection ); if ( m_mainPlotCollection ) { if ( activeOilField()->cloudDataCollection() ) { uiTreeOrdering.add( activeOilField()->cloudDataCollection() ); } } } else if ( uiConfigName == "MainWindow.DataSources" ) { RimOilField* oilField = activeOilField(); if ( oilField ) { if ( oilField->analysisModels() ) uiTreeOrdering.add( oilField->analysisModels() ); // Also shown in the plot window, see "PlotWindow.Cloud". A data source serves both windows: summary // ensembles are created from it there, grid ensembles here, where the grid is going to be used. if ( oilField->cloudDataCollection() ) uiTreeOrdering.add( oilField->cloudDataCollection() ); } uiTreeOrdering.add( &m_ensembleFileSetCollection ); } else { // Use object instead of field to avoid duplicate entries in the tree view uiTreeOrdering.add( viewLinkerCollection() ); RimOilField* oilField = activeOilField(); if ( oilField ) { if ( oilField->analysisModels() ) uiTreeOrdering.add( oilField->analysisModels() ); if ( oilField->genericViewCollection() ) uiTreeOrdering.add( oilField->genericViewCollection() ); if ( oilField->geoMechModels() ) uiTreeOrdering.add( oilField->geoMechModels() ); if ( oilField->wellPathCollection() ) uiTreeOrdering.add( oilField->wellPathCollection() ); if ( oilField->polygonCollection() ) uiTreeOrdering.add( oilField->polygonCollection() ); if ( oilField->surfaceCollection() ) uiTreeOrdering.add( oilField->surfaceCollection() ); if ( oilField->seismicDataCollection() ) { auto child = uiTreeOrdering.add( "Seismic", ":/Seismic16x16.png" ); child->add( oilField->seismicDataCollection() ); child->add( oilField->seismicViewCollection() ); } if ( oilField->formationNamesCollection() ) uiTreeOrdering.add( oilField->formationNamesCollection() ); if ( oilField->completionTemplateCollection() ) uiTreeOrdering.add( oilField->completionTemplateCollection() ); if ( oilField->annotationCollection() ) uiTreeOrdering.add( oilField->annotationCollection() ); if ( oilField->eclipseContourMapCollection() ) uiTreeOrdering.add( oilField->eclipseContourMapCollection() ); } uiTreeOrdering.add( colorLegendCollection() ); } uiTreeOrdering.skipRemainingChildren( true ); }