You are on page 1of 30

2

Schlumberger Private Customer Use

Getting Started with the OFM API

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

Getting Started with the OFM API

Schlumberger Private Customer Use

Schlumberger Private Customer Use

Getting Started with the OFM API

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

Getting Started with the OFM API

Schlumberger Private Customer Use

Schlumberger Private Customer Use

Getting Started with the OFM API

Introduction

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.

Getting Started with the OFM API

Schlumberger Private Customer Use

Prerequisites

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

Schlumberger Private Customer Use

Getting Started with the OFM API

Overview of OFM plugins

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.

Getting Started with the OFM API

Schlumberger Private Customer Use

Overview of OFM plugins

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.

10

Schlumberger Private Customer Use

Getting Started with the OFM API

Overview of OFM plugins


[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:

Getting Started with the OFM API

Schlumberger Private Customer Use

11

Overview of OFM plugins

Figure 1

12

Schlumberger Private Customer Use

Getting Started with the OFM API

Overview of OFM plugins

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.

Getting Started with the OFM API

Schlumberger Private Customer Use

13

Overview of OFM plugins

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 examples 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.

14

Schlumberger Private Customer Use

Getting Started with the OFM API

Sample plugins

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
DATAAPI
DERIVATIVE
EQUINOX
MULTIPLIER

WHAT IT DOES
Illustrates how project information can be obtained and displayed
in a user-defined layout
Calculates the first derivative with respect to time for a userdefined variable
Identifies a date as belonging to a particular equinox (e.g. summer,
winter)
A simple calculation whereby a user defined variable is multiplied
by a user-defined constant

LANGUAGE
C#
VB.NET
C#
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:

Getting Started with the OFM API

Schlumberger Private Customer Use

15

Overview of 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 plugins 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:

16

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.

Schlumberger Private Customer Use

Getting Started with the OFM API

Overview of the OFM API

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.

Getting Started with the OFM API

Schlumberger Private Customer Use

17

Overview of 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.

18

Schlumberger Private Customer Use

Getting Started with the OFM API

Creating a plugin assembly

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:

Getting Started with the OFM API

Schlumberger Private Customer Use

19

Writing a function plugin

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:

20

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();

Schlumberger Private Customer Use

Getting Started with the OFM API

Writing a function plugin

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.

Getting Started with the OFM API

Schlumberger Private Customer Use

21

Writing an analysis plugin

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 arent 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.

22

Schlumberger Private Customer Use

Getting Started with the OFM API

Writing an analysis plugin

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 plugins Context Ribbon and on the plugins 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 plugins Context Ribbon and on the plugins 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)
;

Getting Started with the OFM API

Schlumberger Private Customer Use

23

Writing an analysis plugin

24

Schlumberger Private Customer Use

Getting Started with the OFM API

Compiling (Building) your plugin

Compiling (Building) your plugin


To compile (or build) your plugin into the DLL that OFM will execute, follow these steps.
1.
2.
3.
4.

Prepare your Visual Studio session to build your plugin(s) in the preferred location.
Compile your plugin.
Check that your DLL is in the correct location.
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].

Getting Started with the OFM API

Schlumberger Private Customer Use

25

Compiling (Building) your plugin

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.

26

Schlumberger Private Customer Use

Getting Started with the OFM API

Compiling (Building) your plugin


3. If this is the first time you have used OFM 2014, you will see OFMs default location folder for plugins
selected.
If you wish to use this default folder:
a.
b.
c.
d.

Close the dialog.


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

If you wish to use your chosen folder:


a.
b.
c.
d.

Select the Use an alternate location for Plugins button


Enter your folder location
Close the dialog
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.

Getting Started with the OFM API

Schlumberger Private Customer Use

27

Compiling (Building) your plugin


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.

28

Schlumberger Private Customer Use

Getting Started with the OFM API

FAQ

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.

Getting Started with the OFM API

Schlumberger Private Customer Use

29

FAQ

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 doesnt 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.

30

Schlumberger Private Customer Use

Getting Started with the OFM API

You might also like