30

Getting Started With the OFM API

Embed Size (px)

DESCRIPTION

Getting Started With the OFM API 2014

Citation preview

Page 1: Getting Started With the OFM API
Page 2: Getting Started With the OFM API

2 Schlumberger Private – Customer Use Getting Started with the OFM API

Page 3: Getting Started With the OFM API

Getting Started with the OFM API Schlumberger Private – Customer Use 3

Copyright © 1998-2014 Schlumberger. All rights reserved. This work contains the confidential and proprietary trade secrets of Schlumberger and may not be copied or stored in an information retrieval system, transferred, used, distributed, translated or retransmitted in any form or by any means, electronic or mechanical, in whole or in part, without the express written permission of the copyright owner. Service Marks Schlumberger, the Schlumberger logotype, and other words or symbols used to identify the products and services described herein are either trademarks, trade names or service marks of Schlumberger and its licensors, or are the property of their respective owners. These marks may not be copied, imitated or used, in whole or in part, without the express prior written permission of Schlumberger. In addition, covers, page headers, custom graphics, icons, and other design elements may be service marks, trademarks, and/or trade dress of Schlumberger, and may not be copied, imitated, or used, in whole or in part, without the express prior written permission of Schlumberger. Other company, product, and service names are the properties of their respective owners. An asterisk (*) is used throughout this document to designate a mark of Schlumberger. Product Information Country of Origin: USA Release Date: August 2014

Page 4: Getting Started With the OFM API

4 Schlumberger Private – Customer Use Getting Started with the OFM API

Page 5: Getting Started With the OFM API

Getting Started with the OFM API Schlumberger Private – Customer Use 5

Contents Introduction ................................................................................................................................................................7

Prerequisites ...............................................................................................................................................................8

Installing Visual Studio............................................................................................................................................8

Installing .NET 4.5 ...................................................................................................................................................8

Overview of OFM plugins ...........................................................................................................................................9

Function plugins .................................................................................................................................................. 10

Analysis plugins ................................................................................................................................................... 13

Sample plugins ......................................................................................................................................................... 15

Overview of the OFM API ........................................................................................................................................ 16

Application level functionality ............................................................................................................................. 16

IUiDriver interface ........................................................................................................................................... 16

Workspace level functionality ............................................................................................................................. 16

Data objects ..................................................................................................................................................... 17

Creating a plugin assembly ...................................................................................................................................... 19

Writing a function plugin ......................................................................................................................................... 20

Method 1 ............................................................................................................................................................. 20

Method 2 ............................................................................................................................................................. 21

When things go wrong ........................................................................................................................................ 21

Writing an analysis plugin........................................................................................................................................ 22

The basics ............................................................................................................................................................ 22

Integrating the plugin with the OFM application ................................................................................................ 23

Compiling (Building) your plugin ............................................................................................................................. 25

Prepare your Visual Studio session ..................................................................................................................... 25

Compile your plugin ............................................................................................................................................ 25

Check that your DLL is in the right location ......................................................................................................... 26

Check and run your plugin in OFM ...................................................................................................................... 26

FAQ .......................................................................................................................................................................... 29

Page 6: Getting Started With the OFM API

6 Schlumberger Private – Customer Use Getting Started with the OFM API

Page 7: Getting Started With the OFM API

Introduction

Getting Started with the OFM API Schlumberger Private – Customer Use 7

Introduction The OFM API allows third-party developers to extend the OFM application in controlled ways. The two key areas of extensibility are OFM Functions and OFM Analyses.

Page 8: Getting Started With the OFM API

Prerequisites

8 Schlumberger Private – Customer Use Getting Started with the OFM API

Prerequisites • Visual Studio development environment 2012 or higher • .NET Framework 4.5 or higher • References to the following assemblies:

o Slb.Production.Ofm.Api.dll o Slb.Production.Ofm.Api.PlugIn.dll o Slb.Production.Common.Diagnostics.dll

Installing Visual Studio 1. If you do not already have Visual Studio 2012 or higher installed, you may obtain a free version of Visual

Studio Express 2013 here:

http://www.microsoft.com/en-us/download/details.aspx?id=40787

2. Click Download:

3. Choose the wdexpress-full.exe option. 4. Save the install file and run it from your machine.

Installing .NET 4.5 OFM and OFM plugins require installation of the .NET framework version 4.5 or higher. It may be obtained directly from Microsoft here:

http://www.microsoft.com/en-us/download/details.aspx?id=30653

Page 9: Getting Started With the OFM API

Overview of OFM plugins

Getting Started with the OFM API Schlumberger Private – Customer Use 9

Overview of OFM plugins An OFM plugin is a way to customize, extend, and add value to workflows within OFM. Plugins can leverage OFM and the .NET framework to provide calculations and visualizations that are not currently available in the OFM application.

There are two types of plugins for OFM:

• Function plugins present to OFM in the same way that built-in OFM system functions do, for use in calculations.

• Analysis plugins present to OFM in the same way that built-in Analyses, such as plots and reports, do.

Page 10: Getting Started With the OFM API

Overview of OFM plugins

10 Schlumberger Private – Customer Use Getting Started with the OFM API

Function plugins A Function plugin is a piece of .NET (VB or C#) code that follows a few basic rules so that when it is compiled, the plugin can be recognized by OFM and added to its list of available functions for use in calculations. Plugin functions accept arguments and return results. Both arguments and results may be static or time-dependent.

The Function plugin API is designed to require minimal coding on the part of the plugin writer. The primary target audience for a Function plugin is an engineer who needs to perform a custom calculation in OFM. Here is an example of a simple Function plugin that multiplies an input by a specified factor:

VB:

<OfmFunction("Multiplier", "Multiplier---Multiplies the variable by the specified factor")> _ Private Class MultiplierFunction Inherits BaseFunction Public Function Evaluate(ByVal factor As Double, ByVal array As Result(Of Double)) As Result(Of Double) Dim i As Integer Dim Calculation as Double Dim values As New List(Of Double) For i = 0 to array.Count - 1 Calculation = array.GetValueAt(i) * factor values.Add(Calculation) Next i Return CreateResult(Of Double)(array.PeriodLength, array.SampleTimes, values) End Function End Class

The snippet above originally used LINQ, which may not be intuitive to VB users. Below is a simpler C# workflow which may be easier to understand.

C#:

[OfmFunction("Multiplier", "Multiplier---Multiplies the variable by the specified factor")] class MultiplierFunction : BaseFunction { public Result<double> Evaluate(double factor, Result<double> array) { var multipliedResult = new List<double>(array.Values.Select(d => d * factor)); return CreateResult<double>(array.PeriodLength, array.SampleTimes, multipliedResult); } }

Note the essential, required components of the Function plugin: • The “OfmFunction” attribute tells OFM that this is a Function plugin; • The arguments to the Evaluate function describe the expected arguments to the function; • The CreateResult method returns a Result that matches the return type of the Evaluate function.

What is done between these components is up to the user. Every Function plugin has at its disposal an OFM Workspace object from which nearly all data in the OFM Workspace may be accessed for use in calculations. More information about the OFM Workspace object can be found later in this document.

In the following C# example, notice the use of the Workspace object to access OFM Completions and Variables, and the use of EvaluateVariable to perform an ad-hoc OFM calculation within the Function plugin.

Page 11: Getting Started With the OFM API

Overview of OFM plugins

Getting Started with the OFM API Schlumberger Private – Customer Use 11

[OfmFunction( "ArealMaximum", "Find the maximum value of a variable near the completion specified for the result.")] class ArealMaximum : BaseFunction { public Result<double> Evaluate(double searchRadius, string variableName, string completionName ) { var currentCompletion = Workspace.Completions[completionName]; if (null == currentCompletion) return null; var variable = Workspace.Variables[ variableName ]; if (null == variable || !variable.IsNumeric) return null; var dMaxValue = double.MinValue; foreach (var completion in Workspace.Completions) { if (Distance(currentCompletion, completion) > searchRadius) continue; var dValue = MaxValue(completion, variable); if (dValue > dMaxValue) { dMaxValue = dValue; } } return Math.Abs(dMaxValue - double.MinValue) < 0.00001? CreateEmptyResult<double>() : CreateConstantDoubleResult(dMaxValue); } private double MaxValue(IEntitySource completion, Variable variable) { var result = EvaluateVariable(completion.GetEntity(), variable); if (null == result) return double.MinValue; var doubleResult = result.ConvertTo<double>(); if (null == doubleResult) return double.MinValue; var doubles = doubleResult.Values; if (null == doubles) return double.MinValue; var doubleArray = doubles.ToArray(); return !doubleArray.Any() ? double.MinValue : doubleArray.Max(); } private static double Distance(Completion from, Completion to) { var xSquared = Math.Pow((from.XCoordinate - to.XCoordinate), 2); var ySquared = Math.Pow((from.YCoordinate - to.YCoordinate), 2); return Math.Sqrt(xSquared + ySquared); }

Plugin Functions appear in OFM in the variable editor as new functions that can be entered in equations. They are listed using the “Plugin Functions” button:

Page 12: Getting Started With the OFM API

Overview of OFM plugins

12 Schlumberger Private – Customer Use Getting Started with the OFM API

Figure 1

Page 13: Getting Started With the OFM API

Overview of OFM plugins

Getting Started with the OFM API Schlumberger Private – Customer Use 13

Analysis plugins An analysis plugin is .NET (VB or C#) code that follows a few basic rules so that when it is compiled, the plugin can be recognized by OFM and added to its list of available analyses. Analysis plugins may leverage the OFM content area, the ribbon, the property panel, and the analysis panel.

The Analysis plugin API is designed to minimize coding on the part of the plugin writer. The primary target audience for a Analysis plugin is a .NET developer with enough familiarity with either WinForm or WPF technology to design a user interface for an OFM analysis. Here is a trivial example of an Analysis plugin:

[OfmAnalysis(name: "TrivialAnalysis")] class TrivialAnalysis : Analysis<TrivialAnalysis> { protected override void Initialize(IStatus status) { } private string UserName { get { return GetPropertyValue<string>(); } set { SetPropertyValue(value);} } static private void SendMessage() { // Add code to send a message. } protected override void CreateOfmType(OfmTypeBuilder<TrivialAnalysis> typeBuilder) { typeBuilder.AddProperty<string>("UserName", "User Name") .SetShowInPropertiesPane(true) .SetShowInRibbon(true); typeBuilder.AddCommand("SendMessageCommand", "Send Message", SendMessage, () => true) .SetShowInRibbon(true); } protected override ViewHandle CreateView(ViewHandleBuilder viewHandleBuilder, IStatus status) { var userControl = new UserControl1 {analysisBindingSource = {DataSource = this}}; return viewHandleBuilder.SetWinformHandle(userControl); } protected override void HandleCurrentCategoryChanged(IStatus status) {} protected override void HandleCurrentEntityChanged(IStatus status) {} protected override void HandleCurrentFilterChanged(IStatus status) {} }

Note the essential components of an Analysis plugin: • The “OfmAnalysis” attribute tells OFM that this is an Analysis plugin; • An OFM Analysis plugin must be derived from the API Analysis<> class; • Properties and commands that leverage the Ribbon, the Property Panel and/or the Analysis panel are

added in the CreateOfmType method; • If your Analysis plugin supports WinForm or WPF content, set the reference to that content in the

CreateView method. • Overrides are required for a small number of methods for optional responses to OFM events such as

changes in the current entity or filter.

Page 14: Getting Started With the OFM API

Overview of OFM plugins

14 Schlumberger Private – Customer Use Getting Started with the OFM API

• When an IStatus interface is provided, you may signal errors, warnings, exceptions, or information back to OFM via that interface. Status information may be viewed in OFM via the OFM Status Information dialog.

Also note in the above example’s CreateView method that an Analysis plugin may be set as a data binding source for a WinForm or WPF control. An Analysis plugin implements the INotifyPropertyChanged interface.

Like Function plugins, every Analysis plugin has at its disposal an OFM Workspace object from which nearly all data in the OFM Workspace may be accessed for use in calculations. More information about the OFM Workspace object can be found later in this document.

In addition, an Analysis plugin has available an OFM UiDriver object through which OFM may be directed to perform actions, such as change entities and open Analysis nodes. More information about the OFM UiDriver object can be found later in this document.

Page 15: Getting Started With the OFM API

Sample plugins

Getting Started with the OFM API Schlumberger Private – Customer Use 15

Sample plugins To help you understand the structure of a working plugin, some samples have been included in the installation of OFM 2014. They are located in the following folder:

C:\Program Files (x86)\Schlumberger\OFM 2014\Sample Plugins\Bin

There are 4 plugins:

PLUGIN WHAT IT DOES LANGUAGE DATAAPI Illustrates how project information can be obtained and displayed

in a user-defined layout C#

DERIVATIVE Calculates the first derivative with respect to time for a user-defined variable

VB.NET

EQUINOX Identifies a date as belonging to a particular equinox (e.g. summer, winter)

C#

MULTIPLIER A simple calculation whereby a user defined variable is multiplied by a user-defined constant

C#

While these utilities seem relatively trivial, the code behind them illustrates a wide range of capabilities that the API offers. Each of the plugins, therefore, is also accompanied by its source code. Should you choose to investigate any one of these, simply open (in Visual Studio) the appropriate Solution (.sln) file, such as in the following example for the Derivative plugin:

Page 16: Getting Started With the OFM API

Overview of the OFM API

16 Schlumberger Private – Customer Use Getting Started with the OFM API

Overview of the OFM API The OFM application manipulates one OFM Workspace at a time. The API reflects this by encapsulating application-level and workspace-level functionality in different programmatic objects.

Application level functionality The OFM application is accessed via the IUiDriver interface. The name of interface reflects the fact that it is the OFM application interface subset related to driving the user interface.

IUiDriver interface The IUiDriver interface, accessed through an Analysis plugin’s UiDriver property, includes methods that trigger OFM user interface actions. The general paradigm of these methods is that they trigger the operations in the user interface and return immediately. Completion is signaled via calls to protected methods on the Analysis plugin. As an example, you can change to the next entity by invoking the UiDriver.NextEntity() method, and be certain that the operation is complete when the Analysis<T>. HandleCurrentEntityChanged() method is called. Available methods for the IUiDriver interface are shown in Figure 2:

Figure 2

Workspace level functionality The currently open workspace in the application is represented by a Workspace object. The Workspace class is a sealed class that encapsulates the workspace concept by exposing two general classes of objects:

• Data objects (for example, Completions, Variables) that carry hold data relevant to the workspace. • Service objects (for example, ResultsServices, EntityServices) that are stateless and provide useful

functionality (for example, variable evaluation) not directly tied to one data object.

Page 17: Getting Started With the OFM API

Overview of the OFM API

Getting Started with the OFM API Schlumberger Private – Customer Use 17

Figure 3

Data objects Data objects in the OFM API include (with examples taken from OFM demo databases):

• Categories (for example, “Lease”) • Category Values (for example, “Beringer”) • Completions (for example, “Blue_1:Ge_6”) • Pattern Sets (for example, “regular_five_spot”) • Patterns (for example, “497”) • Variables (for example, “Oil.CalDay”) • Wellbores (for example, “Blue_1”)

ResultsServices The ResultsServices service class includes many helper methods to create and manipulate results.

Results are not direct members of the workspace, but they are scoped to the workspace. Results only exist within the context of the workspace where they were generated and cannot be used in another. Results are the basic data type consumed and produced by OFM Function plugins and are produced by variable evaluation.

At a conceptual level, results are sequences of data values taken or computed at specific points in time. In addition, results have a notion of frequency so that they explicitly express the time periods when the data values apply.

Page 18: Getting Started With the OFM API

Overview of the OFM API

18 Schlumberger Private – Customer Use Getting Started with the OFM API

Figure 4

The API representation of a result is class Result<T> (where T is DateTime, double or string). This in turn derives from class Result, which encapsulates the type-independent portion of the result. APIs that generically consume or return results, are declared using the Result base type but the concrete instance of the results being manipulated is always Result<DateTime>, Result<double> or Result<string>.

EntityServices In addition to the top-level data objects, the API has a concept of “entity” similar to the application itself: entities (represented by class Entity) are objects that ultimately map to a collection of completions. In order to simplify the programming model, the classes that correspond to concepts in OFM that can be used as entities also implement interface IEntitySource which provides access to the corresponding Entity object. Service methods (like ResultsServices.EvaluateVariable) take Entity references to denote the scope of operations/calculations that may apply to one or multiple completions.

Page 19: Getting Started With the OFM API

Creating a plugin assembly

Getting Started with the OFM API Schlumberger Private – Customer Use 19

Creating a plugin assembly The first step to writing an OFM Plugin is to create an assembly to hold them.

Make sure to include the API public assemblies in the Plugin project references:

Page 20: Getting Started With the OFM API

Writing a function plugin

20 Schlumberger Private – Customer Use Getting Started with the OFM API

Writing a function plugin

Method 1 The easiest way to implement a function plugin is to:

1. Derive a public class from the BaseFunction helper class. 2. Attribute it with [OfmFunction(name,description)]. 3. Write an Evaluate() method. Valid parameter/result types are: DateTime, double, string,

Result<DateTime>, Result<double> and Result<string>. 4. To make the plugin assembly visible to OFM, copy it (or set your build output directory) to the “Plugins”

folder in the OFM installation directory. If this directory does not exist, you should create it.

For example:

using System.Linq; using Slb.Production.Ofm.Api; using Slb.Production.Ofm.Api.PlugIn; namespace PluginFunctions { [OfmFunction("CategoriesInWorkspace", "List of Categories in the Workspace")] public class CategoriesInWorkspace : BaseFunction { public Result<string> Evaluate() { var list = Workspace.Categories.Select(category => category.Name).ToList(); return CreateMonthlyResult<string>(2000, 1, list); } } }

The example function plugin lists all the categories in the workspace and returns them in one Result<string>. The result is created using one of the helpers in the ResultsServices class – creating a monthly result, starting in January 2000 in this case.

Behind the scenes:

• The name and description in the attribute appear in the OFM variable editor. • OFM inspects the Evaluate() method via reflection to determine its parameter and result types and

exposes them appropriately to the application. • The BaseFunction class makes two fields available to the Evaluate() method: Workspace and Status.

The former is the current workspace where the function is being evaluated and the latter is an IStatus (from namespace Slb.Production.Common.Diagnostics) implementation where function calculation status can be reported to OFM and the user.

• The BaseFunction class implements IResultsServices so that methods like CreateResult() can be called directly, without having to call Workspace.ResultsServices.CreateResult();

Page 21: Getting Started With the OFM API

Writing a function plugin

Getting Started with the OFM API Schlumberger Private – Customer Use 21

Method 2 The low-level way of implementing an OFM Plugin function is to:

1. Derive from the BaseAbstractFunction class. 2. Explicitly create the function metadata when required. 3. Implement an Evaluate method that is completely expressed in terms of the Result type.

When things go wrong Do not throw exceptions which are unhandled by your plugin. The IStatus interface implementation is provided by OFM to report issues. Throwing an unhandled exception will be interpreted by OFM as a failed Plugin and is liable to cause the function or the whole Plugin to be summarily unloaded.

Page 22: Getting Started With the OFM API

Writing an analysis plugin

22 Schlumberger Private – Customer Use Getting Started with the OFM API

Writing an analysis plugin Analysis plugins integrate with OFM to present themselves as regular view windows. They can interact with the application and workspace to present information in new and interesting ways or drive the application to do things that aren’t easy to perform by hand.

The basics To implement an Analysis plugin:

1. Derive a public class from Analysis<T> and implement the necessary virtual functions in the base class, including returning a ViewHandle from the CreateView override. At a minimum ViewHandle.NoView must be returned if no view is required.

2. Attribute it with [OfmAnalysis(name,largeImageUri,smallImageUri,tabSetName)]. 3. To make the plugin assembly visible to OFM, copy it (or set your build output directory) to the “Plugins”

folder below the location where OFM is run from. If this directory does not exist, you should create it.

For example:

[OfmAnalysis(name: "Iteration Three", largeImageUri: "IterationThreeTest.Resources/dimensionthree_32", smallImageUri: "IterationThreeTest.Resources/dimensionthree_16", tabSetName: "Iteration 3 Tools")] public class IterationThreeAnalysis : Analysis<IterationThreeAnalysis> { … }

The view appears in the OFM ribbon on the Plugins tab with the name and ribbon section specified, but with no special integration with the OFM application.

Page 23: Getting Started With the OFM API

Writing an analysis plugin

Getting Started with the OFM API Schlumberger Private – Customer Use 23

Integrating the plugin with the OFM application Optionally, you can implement the CreateOfmType method in the Analysis plugin to provide a basic level of integration with the application.

Custom commands for the plugin are supported on the plugin’s Context Ribbon and on the plugin’s Property Panel:

typeBuilder.AddCommand("Completions", "Completions", ShowCompletions, () => true) .SetShowInRibbon(true) .SetPanel("Display") .SetLargeImage(Resources.completion_32) .SetSmallImage(Resources.completion_16);

Custom properties for the plugin are supported on the plugin’s Context Ribbon and on the plugin’s Property Panel. Properties may be specified to either persist with the Analysis, or not to persist:

typeBuilder.AddProperty<double>("DoubleProperty", "DoubleProperty") .SetTooltip("Property Only, No Ribbon, No Image") .SetShowInRibbon(false) .SetShowInPropertiesPane(true) .SetTab(tabName) .SetPanel(panelName) ; typeBuilder.AddProperty(x => x.StringPropertyRibbonNoSave, "StringPropertyRibbonNoSave") .SetTooltip("Property and Ribbon, No Image, No Serialization") .SetShowInRibbon(true) .SetShowInPropertiesPane(true) .SetSerializable(false) .SetTab(tabName) .SetPanel(panelName) ;

Page 24: Getting Started With the OFM API

Writing an analysis plugin

24 Schlumberger Private – Customer Use Getting Started with the OFM API

Page 25: Getting Started With the OFM API

Compiling (Building) your plugin

Getting Started with the OFM API Schlumberger Private – Customer Use 25

Compiling (Building) your plugin To compile (or build) your plugin into the DLL that OFM will execute, follow these steps.

1. Prepare your Visual Studio session to build your plugin(s) in the preferred location. 2. Compile your plugin. 3. Check that your DLL is in the correct location. 4. Check and run your plugin in OFM.

Each of these steps is explained in further detail in the following sections.

Prepare your Visual Studio session 1. In Visual Studio, select Project > [Your project] Properties. 2. Select the Compile tab on the left. 3. In the Build Output path entry area, enter the folder which you plan OFM to read your plugins from. Use

the Browse button to navigate.

(Note: the above step is optional. Visual Studio will have its own default location. If you choose not to change it, then you will probably want to relocate your plugin to a more suitable location after you have built it. See step 3 in the Check and run your plugin in OFM section below.)

Compile your plugin 1. In Visual Studio, select Build > Build [Your project].

Page 26: Getting Started With the OFM API

Compiling (Building) your plugin

26 Schlumberger Private – Customer Use Getting Started with the OFM API

Check that your DLL is in the right location 1. Navigate to the plugin output folder you selected above.

You should see a file [Your project].dll. This is your plugin.

2. You may see other build-related output files, such as file types Program Debug Database and XML Document. You may also see replicas of the API libraries (Slb.Production.xxx.dll). You may safely delete all of these files. They are unimportant. (Note that they can be prevented from appearing here by making some settings changes back in Visual Studio.)

Check and run your plugin in OFM 1. Open OFM 2014. 2. On the Workspace tab, select Options > Plugins.

Page 27: Getting Started With the OFM API

Compiling (Building) your plugin

Getting Started with the OFM API Schlumberger Private – Customer Use 27

3. If this is the first time you have used OFM 2014, you will see OFM’s default location folder for plugins selected.

If you wish to use this default folder:

a. Close the dialog. b. Close OFM 2014. c. Move your plugin (the [Your project].dll file) to the default OFM folder. d. Re-open OFM 2014.

If you wish to use your chosen folder:

a. Select the “Use an alternate location for Plugins” button b. Enter your folder location c. Close the dialog d. Close and re-open OFM 2014. (This is necessary so that OFM can read the changed Registry

information.) 4. Confirm that OFM has found your plugin and that it has been accepted.

a. Open a new Report from the main ribbon. b. In the Edit report dialog, confirm that the Plugin Functions button is enabled, and that your

plugin appears on the list when you press the button.

Your plugin is now ready to use. You can use it in exactly the same way you use any System Function – build a Calculated Variable, build a plot header, add it to a report, map it, plot it, forecast it.

Page 28: Getting Started With the OFM API

Compiling (Building) your plugin

28 Schlumberger Private – Customer Use Getting Started with the OFM API

If the plugin did not show up, then check the status bar for errors or messages:

Click on any of these icons if it has a number beside it. A dialog will pop up, providing information as to why your plugin may not have been accepted.

Page 29: Getting Started With the OFM API

FAQ

Getting Started with the OFM API Schlumberger Private – Customer Use 29

FAQ In this section are a few suggestions for some common problems that may arise during the building and execution of your plugins.

How do I deal with the Nulls in my code? Elaboration: One of my plugin function arguments contains Null data values, and the plugin has failed to return anything.

Answer: Your code should contain a sub-section which tests for a (double precision numeric) data value being Null.

In VB .Net it could look like this:

If Double.IsNaN(datavalue) Then <tasks to perform if datavalue is a Null> (IsNaN means “is not a number”) Else <tasks to perform if datavalue is not a Null> End If

In C# you may want to try this:

if( Double.IsNaN(datavalue) { <tasks to perform if datavalue is a Null> (IsNaN means “is not a number”) } else { <tasks to perform if datavalue is not a Null> }

Do I need all of the files in my Plugins folder? Elaboration: When I build my plugin I see lots of files in my Plugins folder.

Answer: No. You only need the DLL file named for your plugin. All other files can be safely deleted. Note that you can prevent the redundant files from appearing in the Plugins folder by setting the relevant Local Copy property for your assemblies to False in the Visual Studio environment.

How do I use my plugin in OFM? Answer: You use it exactly the same way as you would a conventional System Function. You prefix it with @, and can use it to create Calculated Variables, headers and reports.

Can I call another plugin function as an argument in my own plugin function? Answer: Yes.

How do I share my plugin function with my colleagues? Answer: As long as they are also using OFM 2014, and have an Plugins folder, they can simply copy your DLL into that folder.

Page 30: Getting Started With the OFM API

FAQ

30 Schlumberger Private – Customer Use Getting Started with the OFM API

Can the plugins write back to project databases through the API? Elaboration: Can I use a plugin function to do a calculation, create a table in my project and post the results to the table?

Answer: At this time, plugins are unable to write back to project databases through the API.

Can a plugin function return two separate result lists? Answer: No. OFM expects a plugin function to return a one-dimensional array of values.

Why can't I see my plugin function in the list of plugin functions in OFM? Elaboration: I compiled my plugin function and placed it in the Plugins directory.

Answer: Make sure you have “decorated” your function with the OfmFunction attribute. Also; click the “Information Messages” icon in the lower right of the OFM status bar to see if OFM has reported any errors loading your function plugin.

Do I need to add my own plugins to the same Visual Studio project? Elaboration: The plugin functions I can see in my OFM 2014 project were all built in one Visual Studio project. Do I need to add my own plugins to the same project?

Answer: No. Your plugins can be entirely separate. They will need to contain their own configurations (references, build path, etc). However, by adding new plugin code to the same Visual Studio “solution” you can take advantage of the configurations which have already been made in setting up that solution.

What do I do if I want to make changes to my plugin? Answer: Simply close OFM, then re-open the project in Visual Studio, make your changes, rebuild your DLL and re-launch OFM. A new build will overwrite an old one.

What if I need to pass an integer, or a date, into my plugin? Elaboration: The documentation suggests I can only pass in numeric (double) and String data types.

Answer: Declare the argument as Double, then use your code to re-convert it back to the relevant data type. An OFM date will be passed in as a Double with the format YYYYMMDD.

How can I write a plugin without creating a new link in the analysis tree? Elaboration: Is there a way to write a plugin so that every time it is launched, it doesn’t create a new link in the analysis tree?

Answer: The [OfmAnalysis] attribute has a setting that is intended to restrict the number of open instances of a plugin Analysis to one:

[OfmAnalysis(name: "WinFormTest", instances: AnalysisInstances.OnePerWorkspace)]

With this setting, when the first instance is opened, the ribbon control that would launch a new instance is disabled.