Getting Started With The OFM API
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
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.
Prerequisites
Prerequisites
2. Click Download:
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.
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:
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#:
10
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:
11
Figure 1
12
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) {}
}
13
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
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:
15
Figure 2
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.
Figure 3
Data objects
Data objects in the OFM API include (with examples taken from OFM demo databases):
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.
17
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
19
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();
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.
21
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
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)
;
23
24
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.
(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.)
25
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.)
26
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.
27
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
FAQ
FAQ
In this section are a few suggestions for some common problems that may arise during the building and
execution of your plugins.
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
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.
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.
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