From cac9d9d3f953c90bd69f0bf163a9d8e0172b0a2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jacob=20St=C3=B8ren?= Date: Wed, 4 Sep 2013 08:03:11 +0200 Subject: [PATCH] Octave Interface: Added riGetWellStatus p4#: 22301 --- ApplicationCode/CMakeLists.txt | 1 + .../SocketInterface/RiaWellDataCommands.cpp | 230 ++++++++++++ .../ssihubInterface/CMakeLists.txt | 4 + .../ssihubInterface/RimOilFieldEntry.cpp | 56 +++ .../ssihubInterface/RimOilFieldEntry.h | 18 +- .../ssihubInterface/RimOilRegionEntry.h | 6 +- .../ssihubInterface/RimWellCollection.cpp | 45 +++ .../ssihubInterface/RimWellCollection.h | 39 ++ .../ssihubInterface/RimWellPathImport.cpp | 7 +- .../ssihubInterface/RimWellPathImport.h | 10 +- .../ssihubInterface/RimWellsEntry.cpp | 123 +++++++ .../ssihubInterface/RimWellsEntry.h | 64 ++++ .../ssihubInterface/RiuWellImportWizard.cpp | 335 +++++++++++++----- .../ssihubInterface/RiuWellImportWizard.h | 58 ++- .../ssihubInterface/ssihubInterface.cpp | 4 + .../ssihubInterfaceTestApp/main.cpp | 5 + OctavePlugin/CMakeLists.txt | 4 + OctavePlugin/riGetWellNames.cpp | 129 +++++++ OctavePlugin/riGetWellStatus.cpp | 207 +++++++++++ OctavePlugin/riSettings.h | 4 + ResInsightVersion.cmake | 2 +- 21 files changed, 1229 insertions(+), 122 deletions(-) create mode 100644 ApplicationCode/SocketInterface/RiaWellDataCommands.cpp create mode 100644 ApplicationCode/ssihubInterface/RimWellCollection.cpp create mode 100644 ApplicationCode/ssihubInterface/RimWellCollection.h create mode 100644 ApplicationCode/ssihubInterface/RimWellsEntry.cpp create mode 100644 ApplicationCode/ssihubInterface/RimWellsEntry.h create mode 100644 OctavePlugin/riGetWellNames.cpp create mode 100644 OctavePlugin/riGetWellStatus.cpp diff --git a/ApplicationCode/CMakeLists.txt b/ApplicationCode/CMakeLists.txt index 447fe16230..b481ccb2ce 100644 --- a/ApplicationCode/CMakeLists.txt +++ b/ApplicationCode/CMakeLists.txt @@ -54,6 +54,7 @@ set( SOCKET_INTERFACE_FILES SocketInterface/RiaCaseInfoCommands.cpp SocketInterface/RiaGeometryCommands.cpp SocketInterface/RiaPropertyDataCommands.cpp + SocketInterface/RiaWellDataCommands.cpp SocketInterface/RiaSocketTools.cpp ) diff --git a/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp b/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp new file mode 100644 index 0000000000..e47a7c202e --- /dev/null +++ b/ApplicationCode/SocketInterface/RiaWellDataCommands.cpp @@ -0,0 +1,230 @@ +// +// Copyright (C) 2011-2012 Statoil ASA, 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 "RiaStdInclude.h" +#include "RiaSocketCommand.h" +#include "RiaSocketServer.h" +#include "RiaSocketTools.h" + +#include "RiuMainWindow.h" + +#include "RigCaseData.h" +#include "RigCaseCellResultsData.h" + +#include "RimReservoirCellResultsCacher.h" +#include "RimCase.h" +#include "RimInputCase.h" +#include "RimInputPropertyCollection.h" +#include "RimUiTreeModelPdm.h" +#include "RimReservoirView.h" +#include "RimResultSlot.h" +#include "RimCellEdgeResultSlot.h" +#include "RimCellRangeFilterCollection.h" +#include "RimCellPropertyFilterCollection.h" +#include "RimWellCollection.h" +#include "Rim3dOverlayInfoConfig.h" + +#include + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RiaGetWellNames : public RiaSocketCommand +{ +public: + static QString commandName () { return QString("GetWellNames"); } + + virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + { + int caseId = args[1].toInt(); + RimCase* rimCase = server->findReservoir(caseId); + if (!rimCase) + { + server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the case with ID : \"%1\"").arg(caseId)); + + return true; + } + + std::vector wellNames; + + const cvf::Collection& wells = rimCase->reservoirData()->wellResults(); + + for (size_t wIdx = 0; wIdx < wells.size(); ++wIdx) + { + wellNames.push_back(wells[wIdx]->m_wellName); + } + + quint64 byteCount = sizeof(quint64); + quint64 wellCount = wellNames.size(); + + for (size_t wIdx = 0; wIdx < wellCount; wIdx++) + { + byteCount += wellNames[wIdx].size() * sizeof(QChar); + } + + socketStream << byteCount; + socketStream << wellCount; + + for (size_t wIdx = 0; wIdx < wellCount; wIdx++) + { + socketStream << wellNames[wIdx]; + } + + return true; + } +}; + +static bool RiaGetWellNames_init = RiaSocketCommandFactory::instance()->registerCreator(RiaGetWellNames::commandName()); + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +class RiaGetWellStatus : public RiaSocketCommand +{ +public: + static QString commandName () { return QString("GetWellStatus"); } + + virtual bool interpretCommand(RiaSocketServer* server, const QList& args, QDataStream& socketStream) + { + int caseId = args[1].toInt(); + QString wellName = args[2]; + + RimCase* rimCase = server->findReservoir(caseId); + if (!rimCase) + { + server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the case with ID : \"%1\"").arg(caseId)); + + return true; + } + + // Create a list of all the requested time steps + + std::vector requestedTimesteps; + //First find the well result for the correct well + + const cvf::Collection& allWellRes = rimCase->reservoirData()->wellResults(); + cvf::ref currentWellResult; + for (size_t tsIdx = 0; tsIdx < allWellRes.size(); ++tsIdx) + { + if (allWellRes[tsIdx]->m_wellName == wellName) + { + currentWellResult = allWellRes[tsIdx]; + break; + } + } + + if (currentWellResult.isNull()) + { + server->errorMessageDialog()->showMessage( + RiaSocketServer::tr("ResInsight SocketServer: \n") + RiaSocketServer::tr("Could not find the well with name : \"%1\"").arg(wellName)); + + return true; + } + + + if (args.size() <= 3) + { + // Select all timesteps. + + for (size_t tsIdx = 0; tsIdx < currentWellResult->m_resultTimeStepIndexToWellTimeStepIndex.size(); ++tsIdx) + { + requestedTimesteps.push_back(tsIdx); + } + } + else + { + bool timeStepReadError = false; + for (int argIdx = 3; argIdx < args.size(); ++argIdx) + { + bool conversionOk = false; + int tsIdx = args[argIdx].toInt(&conversionOk); + + if (conversionOk) + { + requestedTimesteps.push_back(tsIdx); + } + else + { + timeStepReadError = true; + } + } + + if (timeStepReadError) + { + server->errorMessageDialog()->showMessage(RiaSocketServer::tr("ResInsight SocketServer: riGetGridProperty : \n") + + RiaSocketServer::tr("An error occured while interpreting the requested timesteps.")); + } + } + + std::vector wellTypes; + std::vector wellStatuses; + + for (size_t tsIdx = 0; tsIdx < requestedTimesteps.size(); ++tsIdx) + { + QString wellType = "NotDefined"; + qint32 wellStatus = 0; + if (currentWellResult->hasWellResult(tsIdx)) + { + switch(currentWellResult->wellResultFrame(tsIdx).m_productionType) + { + case RigWellResultFrame::PRODUCER: + wellType = "Producer"; + break; + case RigWellResultFrame::OIL_INJECTOR: + wellType = "OilInjector"; + break; + case RigWellResultFrame::WATER_INJECTOR: + wellType = "WaterInjector"; + break; + case RigWellResultFrame::GAS_INJECTOR: + wellType = "GasInjector"; + break; + } + + wellStatus = currentWellResult->wellResultFrame(tsIdx).m_isOpen ? 1 : 0; + } + + wellTypes.push_back(wellType); + wellStatuses.push_back(wellStatus); + } + + quint64 byteCount = sizeof(quint64); + quint64 timeStepCount = wellTypes.size(); + + for (size_t tsIdx = 0; tsIdx < timeStepCount; tsIdx++) + { + byteCount += wellTypes[tsIdx].size() * sizeof(QChar); + byteCount += sizeof(qint32); + } + + socketStream << byteCount; + socketStream << timeStepCount; + + for (size_t tsIdx = 0; tsIdx < timeStepCount; tsIdx++) + { + socketStream << wellTypes[tsIdx]; + socketStream << wellStatuses[tsIdx]; + } + + return true; + } +}; + +static bool RiaGetWellStatus_init = RiaSocketCommandFactory::instance()->registerCreator(RiaGetWellStatus::commandName()); diff --git a/ApplicationCode/ssihubInterface/CMakeLists.txt b/ApplicationCode/ssihubInterface/CMakeLists.txt index cb544d16e6..7edce9ce7e 100644 --- a/ApplicationCode/ssihubInterface/CMakeLists.txt +++ b/ApplicationCode/ssihubInterface/CMakeLists.txt @@ -43,6 +43,10 @@ add_library( ${PROJECT_NAME} RimOilRegionEntry.cpp RimOilFieldEntry.h RimOilFieldEntry.cpp + RimWellsEntry.h + RimWellsEntry.cpp + RimWellCollection.h + RimWellCollection.cpp RiuWellImportWizard.h RiuWellImportWizard.cpp diff --git a/ApplicationCode/ssihubInterface/RimOilFieldEntry.cpp b/ApplicationCode/ssihubInterface/RimOilFieldEntry.cpp index 1da8721f9e..7c12745e1d 100644 --- a/ApplicationCode/ssihubInterface/RimOilFieldEntry.cpp +++ b/ApplicationCode/ssihubInterface/RimOilFieldEntry.cpp @@ -17,7 +17,13 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimOilFieldEntry.h" +#include "RimWellPathImport.h" +#include "RifJsonEncodeDecode.h" + +#include +#include +#include CAF_PDM_SOURCE_INIT(RimOilFieldEntry, "RimOilFieldEntry"); @@ -54,3 +60,53 @@ caf::PdmFieldHandle* RimOilFieldEntry::objectToggleField() return &selected; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimOilFieldEntry::parseWellsResponse(const QString& absolutePath, const QString& wsAddress) +{ + wells.deleteAllChildObjects(); + + if (QFile::exists(wellsFilePath)) + { + JsonReader jsonReader; + QMap jsonMap = jsonReader.decodeFile(wellsFilePath); + + QMapIterator it(jsonMap); + while (it.hasNext()) + { + it.next(); + + QString key = it.key(); + if (key[0].isDigit()) + { + QMap rootMap = it.value().toMap(); + QMap surveyMap = rootMap["survey"].toMap(); + + { + QString name = surveyMap["name"].toString(); + QMap linksMap = surveyMap["links"].toMap(); + QString requestUrl = wsAddress + linksMap["entity"].toString(); + QString surveyType = surveyMap["surveyType"].toString(); + RimWellPathEntry* surveyWellPathEntry = RimWellPathEntry::createWellPathEntry(name, surveyType, requestUrl, absolutePath, RimWellPathEntry::WELL_SURVEY); + wells.push_back(surveyWellPathEntry); + } + + QMap plansMap = rootMap["plans"].toMap(); + QMapIterator planIt(plansMap); + while (planIt.hasNext()) + { + planIt.next(); + QString name = surveyMap["name"].toString(); + QMap linksMap = surveyMap["links"].toMap(); + QString requestUrl = wsAddress + linksMap["entity"].toString(); + QString surveyType = surveyMap["surveyType"].toString(); + RimWellPathEntry* surveyWellPathEntry = RimWellPathEntry::createWellPathEntry(name, surveyType, requestUrl, absolutePath, RimWellPathEntry::WELL_PLAN); + wells.push_back(surveyWellPathEntry); + } + } + } + } + +} + diff --git a/ApplicationCode/ssihubInterface/RimOilFieldEntry.h b/ApplicationCode/ssihubInterface/RimOilFieldEntry.h index ac404fc5b0..bb2939a4a5 100644 --- a/ApplicationCode/ssihubInterface/RimOilFieldEntry.h +++ b/ApplicationCode/ssihubInterface/RimOilFieldEntry.h @@ -21,7 +21,7 @@ #include "cafPdmObject.h" #include "cafPdmField.h" - +#include "RimWellsEntry.h" @@ -32,13 +32,19 @@ class RimOilFieldEntry : public caf::PdmObject public: RimOilFieldEntry(); - virtual caf::PdmFieldHandle* userDescriptionField(); - virtual caf::PdmFieldHandle* objectToggleField(); + virtual caf::PdmFieldHandle* userDescriptionField(); + virtual caf::PdmFieldHandle* objectToggleField(); + void parseWellsResponse(const QString& absolutePath, const QString& wsAddress); - caf::PdmField name; - caf::PdmField edmId; - caf::PdmField selected; + caf::PdmField name; + caf::PdmField edmId; + caf::PdmField selected; + caf::PdmField wellsFilePath; // Location of the response file from request "/wells" + + caf::PdmPointersField wells; + + }; diff --git a/ApplicationCode/ssihubInterface/RimOilRegionEntry.h b/ApplicationCode/ssihubInterface/RimOilRegionEntry.h index 35f0d023d2..a24ad40e5c 100644 --- a/ApplicationCode/ssihubInterface/RimOilRegionEntry.h +++ b/ApplicationCode/ssihubInterface/RimOilRegionEntry.h @@ -38,9 +38,9 @@ public: virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue); - caf::PdmField name; - caf::PdmField selected; - caf::PdmPointersField fields; + caf::PdmField name; + caf::PdmField selected; + caf::PdmPointersField fields; }; diff --git a/ApplicationCode/ssihubInterface/RimWellCollection.cpp b/ApplicationCode/ssihubInterface/RimWellCollection.cpp new file mode 100644 index 0000000000..c8fbc3873c --- /dev/null +++ b/ApplicationCode/ssihubInterface/RimWellCollection.cpp @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, 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 "RimWellCollection.h" + + +CAF_PDM_SOURCE_INIT(RimWellCollection, "RimWellCollection"); + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellCollection::RimWellCollection() +{ + CAF_PDM_InitObject("OilFieldEntry", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&wells, "Wells", "", "", "", ""); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellCollection::~RimWellCollection() +{ + // Remove all objects in this container, but do not delete the objects + wells.clear(); +} + diff --git a/ApplicationCode/ssihubInterface/RimWellCollection.h b/ApplicationCode/ssihubInterface/RimWellCollection.h new file mode 100644 index 0000000000..158e81c5c4 --- /dev/null +++ b/ApplicationCode/ssihubInterface/RimWellCollection.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" + +#include "RimWellsEntry.h" + + + +class RimWellCollection : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + RimWellCollection(); + ~RimWellCollection(); + + caf::PdmPointersField wells; +}; + + diff --git a/ApplicationCode/ssihubInterface/RimWellPathImport.cpp b/ApplicationCode/ssihubInterface/RimWellPathImport.cpp index cee867c355..87678417a1 100644 --- a/ApplicationCode/ssihubInterface/RimWellPathImport.cpp +++ b/ApplicationCode/ssihubInterface/RimWellPathImport.cpp @@ -29,6 +29,7 @@ namespace caf { setDefault(RimWellPathImport::UTM_FILTER_PROJECT); } + /* template<> void caf::AppEnum< RimWellPathImport::WellTypeEnum >::setUp() { @@ -37,6 +38,7 @@ namespace caf { addItem(RimWellPathImport::WELL_PLAN, "WELL_PLAN", "Plan"); setDefault(RimWellPathImport::WELL_ALL); } + */ } // End namespace caf @@ -52,8 +54,9 @@ RimWellPathImport::RimWellPathImport() { CAF_PDM_InitObject("RimWellPathImport", "", "", ""); - caf::AppEnum defaultWellMode = WELL_ALL; - CAF_PDM_InitField(&wellMode, "WellMode", defaultWellMode, "Well types", "", "", ""); + CAF_PDM_InitField(&wellTypeSurvey, "WellTypeSurvey", true, "Survey", "", "", ""); + CAF_PDM_InitField(&wellTypePlans, "WellTypePlans", true, "Plans", "", "", ""); + CAF_PDM_InitField(&wellTypeAll, "WellTypeAll", true, "All", "", "", ""); caf::AppEnum defaultUtmMode = UTM_FILTER_OFF; CAF_PDM_InitField(&utmFilterMode, "UtmMode", defaultUtmMode, "Utm filter", "", "", ""); diff --git a/ApplicationCode/ssihubInterface/RimWellPathImport.h b/ApplicationCode/ssihubInterface/RimWellPathImport.h index efdfbf5fc0..d836401760 100644 --- a/ApplicationCode/ssihubInterface/RimWellPathImport.h +++ b/ApplicationCode/ssihubInterface/RimWellPathImport.h @@ -31,12 +31,6 @@ class RimWellPathImport : public caf::PdmObject CAF_PDM_HEADER_INIT; public: - enum WellTypeEnum - { - WELL_ALL, - WELL_SURVEY, - WELL_PLAN - }; enum UtmFilterEnum { @@ -48,7 +42,9 @@ public: public: RimWellPathImport(); - caf::PdmField< caf::AppEnum< WellTypeEnum > > wellMode; + caf::PdmField wellTypeSurvey; + caf::PdmField wellTypePlans; + caf::PdmField wellTypeAll; caf::PdmField< caf::AppEnum< UtmFilterEnum > > utmFilterMode; caf::PdmField north; diff --git a/ApplicationCode/ssihubInterface/RimWellsEntry.cpp b/ApplicationCode/ssihubInterface/RimWellsEntry.cpp new file mode 100644 index 0000000000..99ab0dcd17 --- /dev/null +++ b/ApplicationCode/ssihubInterface/RimWellsEntry.cpp @@ -0,0 +1,123 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, 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 "RimWellsEntry.h" +#include "cafAppEnum.h" + + + + +namespace caf { + + template<> + void caf::AppEnum< RimWellPathEntry::WellTypeEnum >::setUp() + { + addItem(RimWellPathEntry::WELL_ALL, "WELL_ALL", "All"); + addItem(RimWellPathEntry::WELL_SURVEY, "WELL_SURVEY", "Survey"); + addItem(RimWellPathEntry::WELL_PLAN, "WELL_PLAN", "Plan"); + setDefault(RimWellPathEntry::WELL_ALL); + } + +} // End namespace caf + + +CAF_PDM_SOURCE_INIT(RimWellPathEntry, "RimWellPathEntry"); + + + + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathEntry::RimWellPathEntry() +{ + CAF_PDM_InitObject("WellPathEntry", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&name, "Name", "Name", "", "", ""); + CAF_PDM_InitField(&selected, "Selected", true, "Selected", "", "", ""); + + caf::AppEnum< RimWellPathEntry::WellTypeEnum > wellType = WELL_ALL; + CAF_PDM_InitField(&wellPathType, "WellPathType", wellType, "Well path type", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&surveyType, "surveyType", "surveyType", "", "", ""); + CAF_PDM_InitFieldNoDefault(&requestUrl, "requestUrl", "requestUrl", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&wellPathFilePath, "wellPathFilePath", "wellPathFilePath", "", "", ""); + +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellPathEntry::userDescriptionField() +{ + return &name; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +caf::PdmFieldHandle* RimWellPathEntry::objectToggleField() +{ + return &selected; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPathEntry* RimWellPathEntry::createWellPathEntry(const QString& name, const QString& surveyType, const QString& requestUrl, const QString& absolutePath, WellTypeEnum wellType) +{ + RimWellPathEntry* entry = new RimWellPathEntry(); + entry->name = name; + entry->surveyType = surveyType; + entry->requestUrl = requestUrl; + entry->wellPathType = wellType; + + QString responseFilePath = undefinedWellPathLocation(); + + int strIndex = requestUrl.indexOf("edm/"); + if (strIndex >= 0) + { + QString lastPart = requestUrl.right(requestUrl.size() - strIndex); + lastPart = lastPart.replace('/', '_'); + + responseFilePath = absolutePath + "/" + lastPart + ".json"; + } + + entry->wellPathFilePath = responseFilePath; + + return entry; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellPathEntry::undefinedWellPathLocation() +{ + return "UNDEFIED_WELLPATH_FILE"; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellPathEntry::isWellPathValid() +{ + return (wellPathFilePath().compare(undefinedWellPathLocation()) != 0); +} + diff --git a/ApplicationCode/ssihubInterface/RimWellsEntry.h b/ApplicationCode/ssihubInterface/RimWellsEntry.h new file mode 100644 index 0000000000..268362f395 --- /dev/null +++ b/ApplicationCode/ssihubInterface/RimWellsEntry.h @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2011-2012 Statoil ASA, 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. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "cafPdmObject.h" +#include "cafPdmField.h" +#include "cafAppEnum.h" + + + + +class RimWellPathEntry : public caf::PdmObject +{ + CAF_PDM_HEADER_INIT; + +public: + enum WellTypeEnum + { + WELL_SURVEY, + WELL_PLAN, + WELL_ALL + }; + + +public: + RimWellPathEntry(); + + static RimWellPathEntry* createWellPathEntry(const QString& name, const QString& surveyType, const QString& requestUrl, const QString& absolutePath, WellTypeEnum wellType); + + + virtual caf::PdmFieldHandle* userDescriptionField(); + virtual caf::PdmFieldHandle* objectToggleField(); + + caf::PdmField name; + caf::PdmField selected; + + caf::PdmField< caf::AppEnum< WellTypeEnum > > wellPathType; + caf::PdmField surveyType; + caf::PdmField requestUrl; + + bool isWellPathValid(); + caf::PdmField wellPathFilePath; // Location of the well path response + +private: + static QString undefinedWellPathLocation(); +}; + + diff --git a/ApplicationCode/ssihubInterface/RiuWellImportWizard.cpp b/ApplicationCode/ssihubInterface/RiuWellImportWizard.cpp index 758873a7ea..10432206a8 100644 --- a/ApplicationCode/ssihubInterface/RiuWellImportWizard.cpp +++ b/ApplicationCode/ssihubInterface/RiuWellImportWizard.cpp @@ -41,6 +41,7 @@ #include "RifJsonEncodeDecode.h" #include "cafPdmUiTreeView.h" +#include "RimWellCollection.h" //-------------------------------------------------------------------------------------------------- @@ -63,11 +64,16 @@ RiuWellImportWizard::RiuWellImportWizard(const QString& webServiceAddress, const addPage(new FieldSelectionPage(m_wellPathImport, NULL, m_pdmTreeView, this)); + addPage(new WellSelectionPage(m_wellPathImport, this)); + m_wellSummaryPageId = addPage(new WellSummaryPage(m_wellPathImport, this)); + m_statusLabel = new QLabel(tr("Status : idle")); m_statusLabel->setWordWrap(true); m_progressDialog = new QProgressDialog(this); + m_wellCollection = new RimWellCollection; + connect(&m_networkAccessManager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(slotAuthenticationRequired(QNetworkReply*,QAuthenticator*))); @@ -120,13 +126,6 @@ QString RiuWellImportWizard::jsonWellsFilePath() return m_destinationFolder + "/wellpaths.json"; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RiuWellImportWizard::downloadWellPaths() -{ - -} //-------------------------------------------------------------------------------------------------- /// @@ -137,17 +136,11 @@ void RiuWellImportWizard::downloadFields() if (QFile::exists(wellFileName)) { QFile::remove(wellFileName); - -// m_wellPathsModel->clear(); -// m_wellPathsModel->setColumnCount(2); - - // clear } m_wellPathImport->regions.deleteAllChildObjects(); m_wellPathImport->updateConnectedEditors(); - QString completeUrlText = m_webServiceAddress + "/resinsight/projects"; QString destinationFileName = jsonFieldsFilePath(); @@ -178,6 +171,7 @@ void RiuWellImportWizard::checkDownloadQueueAndIssueRequests() } + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -200,7 +194,6 @@ void RiuWellImportWizard::issueHttpRequestToFile(QString completeUrlText, QStrin // schedule the request m_httpRequestAborted = false; startRequest(m_url); - } //-------------------------------------------------------------------------------------------------- @@ -266,8 +259,13 @@ void RiuWellImportWizard::httpFinished() if (m_currentDownloadState == DOWNLOAD_WELL_PATH) { + + qDebug() << "Downloaded " << m_file->fileName(); + + /* QString singleWellPathFilePath = m_file->fileName(); + QFile file(singleWellPathFilePath); if (file.open(QFile::ReadOnly)) { @@ -309,6 +307,7 @@ void RiuWellImportWizard::httpFinished() } } } + */ } @@ -319,16 +318,9 @@ void RiuWellImportWizard::httpFinished() delete m_file; m_file = 0; - if (m_currentDownloadState == DOWNLOAD_WELLS) + if (m_currentDownloadState == DOWNLOAD_WELLS || m_currentDownloadState == DOWNLOAD_WELL_PATH) { - QStringList survey; - QStringList plans; - - getWellPathLinks(&survey, &plans); - - m_currentDownloadState = DOWNLOAD_UNDEFINED; - - issueDownloadOfWellPaths(survey, plans); + checkDownloadQueueAndIssueRequests_v2(); } else if (m_currentDownloadState == DOWNLOAD_FIELDS) { @@ -578,6 +570,172 @@ void RiuWellImportWizard::updateFieldsModel() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellImportWizard::downloadWells() +{ + for (size_t rIdx = 0; rIdx < m_wellPathImport->regions.size(); rIdx++) + { + RimOilRegionEntry* oilRegion = m_wellPathImport->regions[rIdx]; + if (oilRegion->selected) + { + for (size_t fIdx = 0; fIdx < oilRegion->fields.size(); fIdx++) + { + RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; + if (oilField->selected) + { + DownloadEntity urlToFile; + + QString wellRequest; + if (m_wellPathImport->utmFilterMode == RimWellPathImport::UTM_FILTER_OFF) + { + wellRequest = QString("/resinsight/projects/%1/wells").arg(oilField->edmId); + } + else + { + wellRequest = QString("/resinsight/projects/%1/wellsInArea?north=%2&south=%3&east=%4&west=%5&utmZone=32N") + .arg(oilField->edmId) + .arg(QString::number(m_wellPathImport->north, 'g', 10)) + .arg(QString::number(m_wellPathImport->south, 'g', 10)) + .arg(QString::number(m_wellPathImport->east, 'g', 10)) + .arg(QString::number(m_wellPathImport->west, 'g', 10)); + } + + urlToFile.requestUrl = m_webServiceAddress + wellRequest; + urlToFile.responseFilename = m_destinationFolder + QString("/wells_%1.json").arg(oilField->edmId); + + oilField->wellsFilePath = urlToFile.responseFilename; + + m_wellRequestQueue.push_back(urlToFile); + } + } + } + } + + m_currentDownloadState = DOWNLOAD_WELLS; + checkDownloadQueueAndIssueRequests_v2(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellImportWizard::downloadWellPaths() +{ + for (size_t rIdx = 0; rIdx < m_wellPathImport->regions.size(); rIdx++) + { + RimOilRegionEntry* oilRegion = m_wellPathImport->regions[rIdx]; + if (oilRegion->selected) + { + for (size_t fIdx = 0; fIdx < oilRegion->fields.size(); fIdx++) + { + RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; + if (oilField->selected) + { + for (size_t wIdx = 0; wIdx < oilField->wells.size(); wIdx++) + { + RimWellPathEntry* wellPathEntry = oilField->wells[wIdx]; + + if (!wellPathEntry->isWellPathValid()) + continue; + + DownloadEntity urlToFile; + + urlToFile.requestUrl = wellPathEntry->requestUrl; + urlToFile.responseFilename = wellPathEntry->wellPathFilePath; + + m_wellRequestQueue.push_back(urlToFile); + } + } + } + } + } + + m_currentDownloadState = DOWNLOAD_WELL_PATH; + + checkDownloadQueueAndIssueRequests_v2(); +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RiuWellImportWizard::checkDownloadQueueAndIssueRequests_v2() +{ + if (m_wellRequestQueue.size() > 0) + { + DownloadEntity firstItem = m_wellRequestQueue[0]; + m_wellRequestQueue.pop_front(); + + QString completeUrlText = firstItem.requestUrl; + QString absoluteFilePath = firstItem.responseFilename; + + issueHttpRequestToFile(completeUrlText, absoluteFilePath); + + return; + } + + + if (m_currentDownloadState == DOWNLOAD_WELLS) + { + m_wellCollection->wells.clear(); + + // Update UI with downloaded wells + + for (size_t rIdx = 0; rIdx < m_wellPathImport->regions.size(); rIdx++) + { + RimOilRegionEntry* oilRegion = m_wellPathImport->regions[rIdx]; + if (oilRegion->selected) + { + for (size_t fIdx = 0; fIdx < oilRegion->fields.size(); fIdx++) + { + RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; + if (oilField->selected) + { + oilField->parseWellsResponse(m_destinationFolder, m_webServiceAddress); + + for (size_t wIdx = 0; wIdx < oilField->wells.size(); wIdx++) + { + m_wellCollection->wells.push_back(oilField->wells[wIdx]); + } + } + } + } + } + + + m_wellCollection->updateConnectedEditors(); + } + else if (m_currentDownloadState == DOWNLOAD_WELL_PATH) + { + WellSummaryPage* wellSummaryPage = dynamic_cast(page(m_wellSummaryPageId)); + if (wellSummaryPage) + { + wellSummaryPage->updateSummaryPage(); + } + } + + m_currentDownloadState = DOWNLOAD_UNDEFINED; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RiuWellImportWizard::~RiuWellImportWizard() +{ + delete m_wellCollection; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellCollection* RiuWellImportWizard::wellCollection() +{ + return m_wellCollection; +} + + @@ -660,102 +818,87 @@ void FieldSelectionPage::initializePage() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QWizardPage* createFieldSelectionPage(RimWellPathImport* wellPathImport) +WellSelectionPage::WellSelectionPage(RimWellPathImport* wellPathImport, QWidget* parent /*= 0*/) { - QWizardPage* page = new QWizardPage; - page->setTitle("Field Selection"); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WellSelectionPage::initializePage() +{ + RiuWellImportWizard* wiz = dynamic_cast(wizard()); + wiz->downloadWells(); QVBoxLayout* layout = new QVBoxLayout; - page->setLayout(layout); + setLayout(layout); - QLabel* label = new QLabel("Select fields"); + QLabel* label = new QLabel("Select wells"); layout->addWidget(label); - // Tree view - caf::PdmUiTreeItem* treeItemRoot = caf::UiTreeItemBuilderPdm::buildViewItems(NULL, -1, wellPathImport); - caf::UiTreeModelPdm* treeModelPdm = new caf::UiTreeModelPdm(page); - treeModelPdm->setTreeItemRoot(treeItemRoot); + m_wellSelectionTreeView = new caf::PdmUiTreeView(this); + m_wellSelectionTreeView->showTree(wiz->wellCollection()); - QTreeView* treeView = new QTreeView(page); - treeView->setModel(treeModelPdm); - layout->addWidget(treeView); + layout->addWidget(m_wellSelectionTreeView); - // Property view - caf::PdmUiPropertyView* propertyView = new caf::PdmUiPropertyView(page); - layout->addWidget(propertyView); - - propertyView->showProperties(wellPathImport); - - return page; } + + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QWizardPage* createLoginPage(const QString& webServiceAddress) +WellSummaryPage::WellSummaryPage(RimWellPathImport* wellPathImport, QWidget* parent /*= 0*/) { - QWizardPage* page = new QWizardPage; - page->setTitle("SSIHUB - Login"); + m_wellPathImportObject = wellPathImport; QVBoxLayout* layout = new QVBoxLayout; + setLayout(layout); - QLabel* label = new QLabel("Please enter your login information for SSIHUB at : " + webServiceAddress); - layout->addWidget(label); + m_textEdit = new QTextEdit(this); - QFormLayout* formLayout = new QFormLayout; - layout->addLayout(formLayout); - - QLineEdit* usernameLineEdit = new QLineEdit(page); - QLineEdit* passwordlLineEdit = new QLineEdit(page); - passwordlLineEdit->setEchoMode(QLineEdit::Password); - - formLayout->addRow("&Username:", usernameLineEdit); - formLayout->addRow("&Password:", passwordlLineEdit); - - page->setLayout(layout); - - - return page; -} -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QWizardPage* createWellPathSelectionPage() -{ - QWizardPage* page = new QWizardPage; - - return page; + layout->addWidget(m_textEdit); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RuiWellImportWizard::showImportWizard(const QString& webServiceAddress, const QString& jsonDestinationFolder) +void WellSummaryPage::initializePage() { - return; - - - ssihub::FetchWellPathsDialog fetchWellPaths; - fetchWellPaths.setSsiHubUrl(webServiceAddress); - fetchWellPaths.setDestinationFolder(jsonDestinationFolder); - //fetchWellPaths.setRegion(m_north, m_south, m_east, m_west); - - QStringList regions, fields, edmIds; - fetchWellPaths.requestFieldData(regions, fields, edmIds); - - - RimWellPathImport* wellPathImport = new RimWellPathImport; - wellPathImport->updateRegions(regions, fields, edmIds); - - - QWizard wizard; - wizard.addPage(createFieldSelectionPage(wellPathImport)); - wizard.addPage(createWellPathSelectionPage()); - - wizard.setField("username", "dymmy"); - wizard.setField("password", "dymmy"); - - wizard.setWindowTitle("ssihub Well Path Import Wizard"); - wizard.exec(); + RiuWellImportWizard* wiz = dynamic_cast(wizard()); + wiz->downloadWellPaths(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void WellSummaryPage::updateSummaryPage() +{ + m_textEdit->setText("Summary of imported wells\n\n"); + + for (size_t rIdx = 0; rIdx < m_wellPathImportObject->regions.size(); rIdx++) + { + RimOilRegionEntry* oilRegion = m_wellPathImportObject->regions[rIdx]; + if (oilRegion->selected) + { + for (size_t fIdx = 0; fIdx < oilRegion->fields.size(); fIdx++) + { + RimOilFieldEntry* oilField = oilRegion->fields[fIdx]; + if (oilField->selected) + { + QString oilFieldText = QString("\nRegion : %1 - Field : %2").arg(oilRegion->name).arg(oilField->name); + m_textEdit->append(oilFieldText); + + for (size_t wIdx = 0; wIdx < oilField->wells.size(); wIdx++) + { + RimWellPathEntry* wellPathEntry = oilField->wells[wIdx]; + QString wellStatus = QString("%1 %2").arg(oilField->wells[wIdx]->name).arg(oilField->wells[wIdx]->wellPathFilePath); + + m_textEdit->append(wellStatus); + } + } + } + } + } } diff --git a/ApplicationCode/ssihubInterface/RiuWellImportWizard.h b/ApplicationCode/ssihubInterface/RiuWellImportWizard.h index 3e5112feb5..d769ef7e2d 100644 --- a/ApplicationCode/ssihubInterface/RiuWellImportWizard.h +++ b/ApplicationCode/ssihubInterface/RiuWellImportWizard.h @@ -27,9 +27,11 @@ class QFile; class QProgressDialog; class QLabel; +class QTextEdit; class RimWellPathImport; +class RimWellCollection; namespace caf @@ -63,6 +65,43 @@ private: }; +class WellSelectionPage : public QWizardPage +{ + Q_OBJECT + +public: + WellSelectionPage(RimWellPathImport* wellPathImport, QWidget* parent = 0); + + virtual void initializePage(); + +private: + caf::PdmUiTreeView* m_wellSelectionTreeView; + +}; + +class WellSummaryPage : public QWizardPage +{ + Q_OBJECT + +public: + WellSummaryPage(RimWellPathImport* wellPathImport, QWidget* parent = 0); + + virtual void initializePage(); + + void updateSummaryPage(); + +private: + RimWellPathImport* m_wellPathImportObject; + QTextEdit* m_textEdit; +}; + + +class DownloadEntity +{ +public: + QString requestUrl; + QString responseFilename; +}; class RiuWellImportWizard : public QWizard { @@ -73,11 +112,14 @@ public: public: RiuWellImportWizard(const QString& webServiceAddress, const QString& downloadFolder, RimWellPathImport* wellPathImportObject, QWidget *parent = 0); + ~RiuWellImportWizard(); void setWebServiceAddress(const QString& wsAdress); void setJsonDestinationFolder(const QString& folder); void setWellPathImportObject(RimWellPathImport* wellPathImportObject); + RimWellCollection* wellCollection(); + private: void startRequest(QUrl url); void setUrl(const QString& httpAddress); @@ -97,8 +139,11 @@ private: public slots: void downloadWellPaths(); + void downloadWells(); void downloadFields(); void checkDownloadQueueAndIssueRequests(); + + void checkDownloadQueueAndIssueRequests_v2(); void issueHttpRequestToFile( QString completeUrlText, QString destinationFileName ); void cancelDownload(); @@ -122,9 +167,10 @@ private: QString m_destinationFolder; RimWellPathImport* m_wellPathImport; -// caf::UiTreeModelPdm* m_treeModelPdm; caf::PdmUiTreeView* m_pdmTreeView; + RimWellCollection* m_wellCollection; + QProgressDialog* m_progressDialog; QUrl m_url; @@ -134,7 +180,8 @@ private: bool m_httpRequestAborted; - QStringList m_wellPathRequestQueue; + QStringList m_wellPathRequestQueue; + QList m_wellRequestQueue; DownloadState m_currentDownloadState; @@ -142,6 +189,8 @@ private: // To be deleted QLabel* m_statusLabel; + int m_wellSummaryPageId; + }; @@ -152,8 +201,3 @@ private: -class RuiWellImportWizard -{ -public: - static void showImportWizard(const QString& webServiceAddress, const QString& jsonDestinationFolder); -}; diff --git a/ApplicationCode/ssihubInterface/ssihubInterface.cpp b/ApplicationCode/ssihubInterface/ssihubInterface.cpp index db6bd9f309..ff2d2985dd 100644 --- a/ApplicationCode/ssihubInterface/ssihubInterface.cpp +++ b/ApplicationCode/ssihubInterface/ssihubInterface.cpp @@ -70,6 +70,7 @@ void Interface::setRegion(int north, int south, int east, int west) //-------------------------------------------------------------------------------------------------- QStringList Interface::jsonWellPaths() { + /* RuiWellImportWizard::showImportWizard(m_webServiceAddress, m_jsonDestinationFolder); FetchWellPathsDialog fetchWellPaths; @@ -84,6 +85,9 @@ QStringList Interface::jsonWellPaths() } return importedWellPathFiles; + */ + + return QStringList(); } }; // namespace ssihub diff --git a/ApplicationCode/ssihubInterfaceTestApp/main.cpp b/ApplicationCode/ssihubInterfaceTestApp/main.cpp index 4caa4443d0..77bd28886f 100644 --- a/ApplicationCode/ssihubInterfaceTestApp/main.cpp +++ b/ApplicationCode/ssihubInterfaceTestApp/main.cpp @@ -44,6 +44,7 @@ #include "ssihubInterface.h" #include "TestTools.h" #include "RiuWellImportWizard.h" +#include "RimWellPathImport.h" @@ -76,6 +77,10 @@ int main(int argc, char *argv[]) // QStringList jsonWellPaths(); RimWellPathImport* wellPathImportObject = TestTools::createMockObject(); + wellPathImportObject->north = north; + wellPathImportObject->south = south; + wellPathImportObject->east = east; + wellPathImportObject->west = west; RiuWellImportWizard wizard(wsAddress, destinationFolder, wellPathImportObject); diff --git a/OctavePlugin/CMakeLists.txt b/OctavePlugin/CMakeLists.txt index a58da500bd..d5dd8141fa 100644 --- a/OctavePlugin/CMakeLists.txt +++ b/OctavePlugin/CMakeLists.txt @@ -20,6 +20,8 @@ set(CPP_SOURCES riGetGridProperty.cpp riSetGridProperty.cpp riGetPropertyNames.cpp + riGetWellNames.cpp + riGetWellStatus.cpp ) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -129,6 +131,8 @@ else() "${CMAKE_CURRENT_BINARY_DIR}/riGetGridProperty.oct" "${CMAKE_CURRENT_BINARY_DIR}/riSetGridProperty.oct" "${CMAKE_CURRENT_BINARY_DIR}/riGetPropertyNames.oct" + "${CMAKE_CURRENT_BINARY_DIR}/riGetWellNames.oct" + "${CMAKE_CURRENT_BINARY_DIR}/riGetWellStatus.oct" SOURCES ${CPP_SOURCES} ) diff --git a/OctavePlugin/riGetWellNames.cpp b/OctavePlugin/riGetWellNames.cpp new file mode 100644 index 0000000000..df72d3dc66 --- /dev/null +++ b/OctavePlugin/riGetWellNames.cpp @@ -0,0 +1,129 @@ +#include +#include +#include + +#include "riSettings.h" + +void getWellNames(std::vector& wellNames, const QString &hostName, quint16 port, + const qint64& caseId) +{ + QString serverName = hostName; + quint16 serverPort = port; + + QTcpSocket socket; + socket.connectToHost(serverName, serverPort); + + if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs)) + { + error((("Connection: ") + socket.errorString()).toLatin1().data()); + return; + } + + // Create command and send it: + + QString command; + command += QString("GetWellNames") + " " + QString::number(caseId); + QByteArray cmdBytes = command.toLatin1(); + + QDataStream socketStream(&socket); + socketStream.setVersion(riOctavePlugin::qtDataStreamVersion); + + socketStream << (qint64)(cmdBytes.size()); + socket.write(cmdBytes); + + // Get response. First wait for the header + + while (socket.bytesAvailable() < (int)(sizeof(quint64))) + { + if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) + { + error((("Waiting for header: ") + socket.errorString()).toLatin1().data()); + return; + } + } + + quint64 byteCount; + socketStream >> byteCount; + + // QString byteCountString = QString::number(byteCount); + //error(byteCountString.toLatin1().data()); + + while (socket.bytesAvailable() < (int)(byteCount)) + { + if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) + { + error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); + return; + } + OCTAVE_QUIT; + } + + quint64 wellCount; + socketStream >> wellCount; + + QString wellName; + + for (size_t i = 0; i < wellCount; i++) + { + socketStream >> wellName; + + wellNames.push_back(wellName); + } + + return; +} + + + +DEFUN_DLD (riGetWellNames, args, nargout, + "Usage:\n" + "\n" + " riGetWellNames([CaseId]) \n" + "\n" + "This function returns the names of all the wells in the case as a Vector of strings.\n" + "If the CaseId is not defined, ResInsight’s Current Case is used.\n" + ) +{ + int nargin = args.length (); + if (nargin > 1) + { + error("riGetWellNames: Too many arguments, this function takes one optional arguments.\n"); + print_usage(); + } + else if (nargout != 1) + { + error("riGetWellNames: Wrong number of output arguments, this function requires one output argument.\n"); + print_usage(); + } + else + { + qint64 argCaseId = -1; + + if (nargin == 1) + { + argCaseId = args(0).uint_value(); + } + + std::vector wellNames; + + getWellNames(wellNames, "127.0.0.1", 40001, argCaseId); + + size_t caseCount = wellNames.size(); + + // Create cells with N items for each field in the data structure + + //charMatrix octaveWellNames; + string_vector octaveWellNames; + for (size_t i = 0; i < caseCount; i++) + { + octaveWellNames.append(wellNames[i].toStdString()); + } + + // Build a map between the field name and field cell values + + return octave_value(octaveWellNames); + } + + return octave_value(); +} + diff --git a/OctavePlugin/riGetWellStatus.cpp b/OctavePlugin/riGetWellStatus.cpp new file mode 100644 index 0000000000..563dbeadd6 --- /dev/null +++ b/OctavePlugin/riGetWellStatus.cpp @@ -0,0 +1,207 @@ +#include +#include +#include + +#include "riSettings.h" + +void getWellStatus(std::vector& wellTypes, std::vector& wellStatuses, const QString &hostName, quint16 port, + const qint64& caseId, const QString& wellName, const int32NDArray& requestedTimeSteps) +{ + QString serverName = hostName; + quint16 serverPort = port; + + QTcpSocket socket; + socket.connectToHost(serverName, serverPort); + + if (!socket.waitForConnected(riOctavePlugin::connectTimeOutMilliSecs)) + { + error((("Connection: ") + socket.errorString()).toLatin1().data()); + return; + } + + // Create command and send it: + + QString command; + command += QString("GetWellStatus") + " " + QString::number(caseId) + " " + wellName; + + for (int i = 0; i < requestedTimeSteps.length(); ++i) + { + if (i == 0) command += " "; + command += QString::number(static_cast(requestedTimeSteps.elem(i)) - 1); // To make the index 0-based + if (i != requestedTimeSteps.length() -1) command += " "; + } + + QByteArray cmdBytes = command.toLatin1(); + + QDataStream socketStream(&socket); + socketStream.setVersion(riOctavePlugin::qtDataStreamVersion); + + socketStream << (qint64)(cmdBytes.size()); + socket.write(cmdBytes); + + // Get response. First wait for the header + + while (socket.bytesAvailable() < (int)(sizeof(quint64))) + { + if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) + { + error((("Waiting for header: ") + socket.errorString()).toLatin1().data()); + return; + } + } + + quint64 byteCount; + socketStream >> byteCount; + + while (socket.bytesAvailable() < (int)(byteCount)) + { + if (!socket.waitForReadyRead(riOctavePlugin::shortTimeOutMilliSecs)) + { + error((("Waiting for data: ") + socket.errorString()).toLatin1().data()); + return; + } + OCTAVE_QUIT; + } + + quint64 timeStepCount; + socketStream >> timeStepCount; + + QString wellType; + qint32 wellStatus; + + for (size_t i = 0; i < timeStepCount; i++) + { + socketStream >> wellType; + socketStream >> wellStatus; + + wellTypes.push_back(wellType); + wellStatuses.push_back(wellStatus); + } + + return; +} + + + +DEFUN_DLD (riGetWellStatus, args, nargout, + "Usage:\n" + "\n" + " riGetWellStatus ([CaseId], WellName, [RequestedTimeSteps]) \n" + "\n" + "This function returns the status information for a specified well for each\n" + "requested time step as a vector of Structures. \n" + "The Structure is defined as:\n" + "WellStatus { \n" + " WellType = string # \"Producer\", \"OilInjector\", \"WaterInjector\", \"GasInjector\", \"NotDefined\" \n" + " WellStatus = int # is either 0 or 1, meaning the well is shut or open respectively.\n" + "}\n" + "If the CaseId is not defined, ResInsight’s Current Case is used.\n" + + ) +{ + if (nargout != 1) + { + error("riGetWellStatus: Wrong number of output arguments, this function requires one output argument.\n"); + print_usage(); + return octave_value(); + } + + int nargin = args.length (); + if (nargin < 1) + { + error("riGetWellStatus: Too few arguments, this function needs at least the well name as input.\n"); + print_usage(); + return octave_value(); + } + + if (nargin > 3) + { + error("riGetWellStatus: Too many arguments, this function takes at most three arguments.\n"); + print_usage(); + return octave_value(); + } + + std::vector argIndices; + argIndices.push_back(0); // caseId + argIndices.push_back(1); // WellName + argIndices.push_back(2); // TimeSteps + + // Check if we do not have a CaseId: + if (args(argIndices[0]).is_string()) // Check if first argument is a text. If it is, the caseId is missing + { + argIndices[0] = -1; + for (size_t aIdx = 1; aIdx < argIndices.size(); ++aIdx) + --argIndices[aIdx]; + } + + // Check if we have a Requested TimeSteps + int lastArgumentIndex = argIndices[2] ; + if (!(nargin > argIndices[2] && args(argIndices[2]).is_matrix_type())) + { + argIndices[2] = -1; + } + + // Check if we have more arguments than we should + if (nargin > lastArgumentIndex + 1) + { + error("riGetWellStatus: Unexpected argument at the end.\n"); + print_usage(); + return octave_value_list (); + } + + // Setup the argument list + + NDArray propertyFrames; + int caseId = -1; + std::string wellName = "UNDEFINED"; + int32NDArray requestedTimeSteps; + + if (argIndices[0] >= 0) caseId = args(argIndices[0]).int_value(); + if (argIndices[1] >= 0) wellName = args(argIndices[1]).char_matrix_value().row_as_string(0); + if (argIndices[2] >= 0) requestedTimeSteps = args(argIndices[2]).int32_array_value(); + + if (wellName == "UNDEFINED") + { + error("riGetWellStatus: The argument must be a text containing the well name.\n"); + print_usage(); + return octave_value(); + } + + std::vector wellType; + std::vector wellStatus; + + getWellStatus(wellType, wellStatus, "127.0.0.1", 40001, caseId, QString::fromStdString(wellName), requestedTimeSteps); + + size_t caseCount = wellType.size(); + + if (wellType.size() != wellStatus.size() ) + { + error("riGetWellStatus: Inconsistent data received from ResInsight.\n"); + } + else + { + // Create cells with N items for each field in the data structure + + Cell cellValuesB(caseCount, 1); + Cell cellValuesC(caseCount, 1); + + for (size_t i = 0; i < caseCount; i++) + { + cellValuesB(i) = wellType[i].toLatin1().data(); + cellValuesC(i) = wellStatus[i]; + } + + // Build a map between the field name and field cell values + + Octave_map m; + + m.assign(riOctavePlugin::wellStatus_WellType, cellValuesB); + m.assign(riOctavePlugin::wellStatus_WellStatus, cellValuesC); + + return octave_value(m); + } + + + +} + diff --git a/OctavePlugin/riSettings.h b/OctavePlugin/riSettings.h index 171108948e..f61f4c9087 100644 --- a/OctavePlugin/riSettings.h +++ b/OctavePlugin/riSettings.h @@ -34,6 +34,10 @@ namespace riOctavePlugin char propertyInfo_PropName[] = "PropName"; char propertyInfo_PropType[] = "PropType"; + // Octave data structure: WellStatus + char wellStatus_WellType[] = "WellType"; + char wellStatus_WellStatus[] = "WellStatus"; + // Octave data structure : CaseGroupInfo char caseGroupInfo_CaseGroupId[] = "CaseGroupId"; char caseGroupInfo_CaseGroupName[] = "CaseName"; diff --git a/ResInsightVersion.cmake b/ResInsightVersion.cmake index f661ca102e..bea8681585 100644 --- a/ResInsightVersion.cmake +++ b/ResInsightVersion.cmake @@ -1,7 +1,7 @@ set(CMAKE_MAJOR_VERSION 0) set(CMAKE_MINOR_VERSION 9) -set(CMAKE_PATCH_VERSION 24) +set(CMAKE_PATCH_VERSION 25) set(PRODUCTVER ${CMAKE_MAJOR_VERSION},${CMAKE_MINOR_VERSION},0,${CMAKE_PATCH_VERSION}) set(STRPRODUCTVER ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION})