Warning: Can't synchronize with repository "(default)" (/media/seamcatrepo does not appear to be a Subversion repository.). Look in the Trac log for more information.

You are here: Manual / Library / Plugins / PostProcessing


Creating an EPP - Event Processing Plugin (version 5.0.0 and above)

EPP information: WARNING. This info is only valid for the Alfa Version:

Creating the Event Processing Plugin

A SEAMCAT Event Processing Plugin must implement the interface EventProcessingPlugin in order for SEAMCAT to communicate with the plugin. This interface is available from the seamcat-model-5.0.0.jar file.

Creating a post processing plugin (version 4.1.0) - PostProcessing will be terminated as of version 5.0.0 and replaced by EPP


Since October 2005, the SEAMCAT-3 was released with a new evolutionary upgrade that allows the user to control the simulations in SEAMCAT EGE by inserting a user-defined Post-processing plugins, which may be called to perform required operations just before the end of EGE snapshot. The purpose with this post-processing plugin is to give many new possibilities to the user, such as:

  • Introduce additional, user-defined consistency checks;
  • Adjust the results of EGE simulations as if accounting for some special features of modelled systems, which otherwise could not be programmed in a standard SEAMCAT scenario description. An example of such special feature could be the use of Smart Antenna in one of the modelled systems, etc.;
  • Introduce additional models for simulation of various components of link budgets, besides the standard models built-in within SEAMCAT-3;
  • To channel intermediate results of EGE simulations into external files for any post-processing in other software tools or to form an input for some other kinds of simulations (e.g. to use data on randomised positioning of terminals generated by SEAMCAT in some other kind of user-developed radio analysis tools, etc).

The user-defined Post-processing plugin could be any software routine, written using Java programming language and compiled as a Java class, with interface compliant with SEAMCAT-3 Post-processing plug-in interface specifications. These interface specifications, as well as the procedures for developing a plug-in and connecting it to SEAMCAT-3 are described in detail below in this section.

An educational example of using Post-processing plugin for implementation of Smart Antenna functionality is presented in the attached PDF

Enable post processing plugins in SEAMCAT

In order to be able to use post processing plugins inside SEAMCAT you first have to enable this feature. This is done through the Configuration menu item on the File menu. After enabling the SEAMCAT application has to be restarted.


Before you can start developing SEAMCAT post processing plugins you will need to ensure that your system has been correctly configured. Information on how to this is located in the Basic Enviroment Setup section.

Note: The SEAMCAT Post processing plugin API leverages many of the language features added with release 1.5 of Java. Therefore plugins MUST be compiled on a Java SE 5 or higher version-compatible compiler, with source option set to 1.5 or higher! Also note that some IDE's (like Eclipse) refers to this as compiler compliance level 5.0.

Before we start

Creating a post processing plugin is very similar to creating propagation model plugins, but can also be more complex. Therefore the use of an Integrated Development Environment (IDE) is advisable. Both of these environments offer a set of tools that will assist you in creating your plugin. It is, however, not within the scope of the SEAMCAT online help to go through setting up these tools.

In the following section it is assumed that the user has a working java development enviroment and is familiar with basic java development terms.

Creating the plugin

A SEAMCAT post processing plugin must implement the interface PostProcessingPlugin in order for SEAMCAT to communicate with the plugin. This interface is available from the seamcat_needed_for_plugin.jar file. (Note: that SEAMCAT automatically overwrites the seamcat_needed_for_plugin.jar file with the latest version. )

In order for SEAMCAT to make scenario information available to the plugin, an instance of a special class called ScenarioInfo is passed as a parameter to the process method. This class gives access to a lot of information and it is important to understand it in order to develop plugins. The ScenarioInfo class also gives access to an instance of the ProcessingResult class which is used by plugins to pass modified values back to SEAMCAT.

If a post processing plugin is only applicable to some specific scenario configuration (for example only a specific frequency range) the plugin can implement the optional interface called ConsistencyCheck. This interface specifies just one method that will be called during normal consistency check of scenario. SEAMCAT will automaticly detect if the plugin implements this interface, and as such no additional configuration is necessary by the plugin developer. The consistency check specified by plugin will only be applied to workspace if that particular plugin has been added to workspace. If several instances of the same plugin has been added (plugin chaining) the check will run once per instance.

When creating the java-file, it is important to observe java-code conventions, ie. the name of the class must match the name of the java-file (for example, the class MyPlugin must be defined in a file called Also, it is recommended to start a class-name with a capital letter.

Sample plugin

For demonstration purposes the source code for a sample plugin is given. The demonstration plugin implements both the mandatory PostProcessingPlugin interface and the optional ConsistencyCheck interface. Feel free to use this source code as the basis for your new plugin.

import org.seamcat.model.plugin.*; import org.seamcat.model.plugin.PluginDistribution.DistributionType;


* SEAMCAT Post Processing Plugin demonstration. * Note that this demo implements the optional ConsistencyCheck interface. * * @author Christian Petersen, IPeople Aps

*/ pubblic class MyPlugin implements PostProcessingPlugin, ConsistencyCheck {

private boolean useRandomFactor = false; private boolean modifyIRSS = false; private int baseValue = 1; private PluginDistribution randomFactor;


* This method is called by SEAMCAT to initialize the plugin. * By using the ParameterFactory complex variables can be created.

*/ public void init(ParameterFactory fact) { randomFactor = fact.createDistribution(DistributionType.Uniform, 0, 1); }


* This method should return some meaningfull description of this plugin */ public String getDescription() { return <span class="string" style="" >"*SEAMCAT* Online help demonstration plugin"</span>; } /**

* This is the method called by EGE to do actual processing

*/ public void process(ScenarioInfo info) throws Exception { double dRSS = info.getVictimLink().getDRSSValue(); if (useRandomFactor) { dRSS -= (baseValue* randomFactor.trial()); } else { dRSS -= baseValue; } if (modifyIRSS) { for (int i = 1;i <= info.getNumberOfInterferingLinks();i++) { double iRSS = info.getInterferingLink(i).getIRSSUnwanted(); if (useRandomFactor) { iRSS -= (baseValue * randomFactor.trial()); } else { iRSS -= baseValue; } info.getProcessingResults().setIRSSUnwanted(i, iRSS); } } info.getProcessingResults().setDRSS(dRSS);

if (info.getCurrentEventNumber() == 12345) { info.requestSimulationStop(); } }


* This method is called by SEAMCAT to determine the number of user configurable parameters.

*/ public int getNumberOfParameters() { return 4; }


* This method is called by SEAMCAT to let GUI determine the type of each parameter

*/ public ParameterType getParameterType(int index) { switch (index) { case 1: {return ParameterType.Boolean;} case 2: {return ParameterType.Integer;} case 3: {return ParameterType.Distribution;} case 4: {return ParameterType.Boolean;} } return null; }


* This method is called by SEAMCAT whenever user changes the value of a parameter through the GUI

*/ public void setParameterValue(int index, Object value) { switch (index) { case 1: { useRandomFactor = (Boolean) value; break; } case 2: { baseValue = (Integer) value; break; } case 3: { randomFactor = (PluginDistribution) value; break; } case 4: { modifyIRSS = (Boolean) value; break; } } }


* This method is called by SEAMCAT to determine the current value of each parameter.

*/ public Object getParameterValue(int index) { Object value = null; switch (index) { case 1: {value = useRandomFactor; break;} case 2: {value = baseValue; break;} case 3: {value = randomFactor; break;} case 4: {value = modifyIRSS; break;} } return value; }


* This method is called by SEAMCAT to initialize GUI with the correct name for each parameter

*/ public String getParameterName(int index) { String name = null; switch (index) { case 1: {name = <span class="string" style="" >"Use random factor?"</span>; break;} case 2: {name = <span class="string" style="" >"Base value to substract"</span>; break;} case 3: {name = <span class="string" style="" >"Random factor"</span>; break;} case 4: {name = <span class="string" style="" >"Modify iRSS Vectors?"</span>; break;} } return name; }


* This method is called by SEAMCAT to indicate that current simulation is over. If plugin has any open files they should be closed here.

*/ public void cleanUp() { //We do not have any open ressources and therefore we do no clean up. //Note that simulation might run again without any calls to init or setParameter. //Therefore plugin should always check its ressources in the process method. }


* This method is specified by the ConsistencyCheck interface and is called by SEAMCAT during general consistency check

*/ public* boolean* check(ScenarioInfo info) { if (info.getNumberOfInterferingLinks() < 2) { info.addConsistencyWarning(<span class="string" style="" >"MyPlugin is ONLY applicable on scenarios with 2 or more interfering links"</span>); return false; } else { return true; } } }

All methods in the class above are specified by the PostProcessingPlugin interface.

The first method is the init method which takes a ParameterFactory as input parameter. This factory is used to create new instances of complex parameters such as Distributions and Functions (either Function2D or Function3D).

This is to ensure that plugins are using the same internal versions of these classes as rest of SEAMCAT. Note that the ParameterFactory.createDistribution() method takes an arbitrary number of double parameters after the type. This way all the standard distributions in SEAMCAT can be initialized correctly. For at full description on how to create each distribution type please refer to the javadoc for the ParameterFactory class.

The second method implemented is the getDescription method. This should return a string that describes your plugin. This string can use simple HTML-alike formatting.

The third method is the process method which does the actual calculations. As this method will be called at least once per snapshot you should make sure that it runs effectively. Note: This implementation is very simple and does not inspect the actual scenario as is probally needed by production plugin. The access to scenario information is done through the ScenarioInfo object.

The next five methods takes care of parameters and should be straight forward. These methods will allow the user to configure a plugin through the SEAMCAT user interface. There is no limit to the number of parameters, and, of course, not all parameters need to be configurable by user.

Here is a step by step walk through of the parameter handling methods.

 public int getNumberOfParameters()

This method is called by SEAMCAT to query the total number of parameters that a user should see. Since parameter indexes are 1-based this is also the highest parameter index. All methods below take a parameter index as input and this is guaranteed to be in the range of 1 - getNumberOfParameters().

 public ParameterType getParameterType(int index)

This method is called by SEAMCAT to determine the type of a given parameter. The information is used by user interface to present a proper selection of values to the user. The returned value has to be a member of the ParameterType enumeration defined on the interface.

In the demo-example above a switch statement is used to return the proper type. This approach will be applicable for many plugins.

 public void setParameterValue(int index, Object value)

This method will be called by SEAMCAT when a user configures the plugin. The plugin is responsible for storing the values in the correct local parameters. SEAMCAT will handle persistence of parameter values.

Note:_ Multiple instances of the same plugin may be made theerefore the use of static variables should be avoided.

In the example, a simple switch statement is used to determine which parameter to set. Then an explicit cast is being used to convert the given Object value to the specialized type of the parameter.

Note: This example uses the JDK1.5 feature called auto-boxing to convert between native and Object representation of primitive numbers. Therefore this example will not compile on any JDK earlier than version 1.5.

 public Object getParameterValue(int index)

Called by SEAMCAT to retrieve the current value of a given parameter. The returned value must conform with the parameter type for the given index.

The example continues to use a simple switch statement on the given index.

 public Object getParameterName(int index)

Called by SEAMCAT to retrieve the name of a given parameter. This name will be shown to user in order to assist in configuration of plugin.

The example continues to use a simple switch statement on the given index to return the correct name.

 public void cleanUp()

The method named cleanUp() is called by SEAMCAT to indicate to plugin that EGE run is over. This allows plugin to close any open ressources (such as files or database connections). In the example above this method does nothing as we do not have anyressources open.

 public* boolean* check(ScenarioInfo info)

The last method, named check(ScenarioInfo info) is called by SEAMCAT during consistency check of scenario. After running the standard SEAMCAT checks this method will called on all plugin instances that implement the ConsistencyCheck interface, for the workspace being checked.

How to add your plugin to SEAMCAT

See the instruction for the propagation model plugin It is the same principal.

A practical example is also given in

How to use your plugin

Under the menu item Workspace / Post processing plugins This will allow you to configure post processing for the current workspace.

Select a plugin in the dropdown menu and click the add button. It is possible to add the same plugin multiple times in which case multiple instances will be created each having individual configurations. The sequence, in which the plugins will be run, is in ascending order according to the index on the lefthand side of the list.

To configure a plugin, select it in the list and click configure.

Here it is possible to rename this specific instance of the plugin as well as modify parameters. Simple parameters (Boolean, Integer and Double) are modified directly in table whereas complex parameters are modified by doubleclicking.

Running EGE

The event generation is started as usual and the EGE will itself detect the presence of any plugins configured for workspace. If plugins exist the EGE will run them and store the signal vectors after the plugin has completed.

Note: The plugin itself is responsible for signal consistency! This means that if a plugin modifies the unwanted value it should also update blocking and intermodulation vectors accordingly.

Available Mathematical functions

Q: Which mathematical functions are available to plugin, and what are they called?
A: Any Java class have access to the functions defined by the java.lang.Math class, and theese are called as static functions on the class.


  //the following line calls the Log10 function from the java.lang.Math class 
double logValue = Math.log10(myInput); ...

The complete list of functions available from java.lang.Math can be found here. Besides giving access to the standard math functions a SEAMCAT plugin can access a series of SEAMCAT defined mathematical functions. These are all located in the org.seamcat.mathematics.Mathematics class. The use of this library of functions is similar to the use of the standard library, but there are a few differencies. First of all an additional import statement is needed at the top plugin class file. The following line must be included before SEAMCATs internal math functions can be used:

 import org.seamcat.mathematics.Mathematics;

After adding import statement, functions can be called by using the Mathematics prefix.


  //the following line calls the decimal based tangent function from
// the org.seamcat.mathematics.Mathematics class 
double tanDValue = Mathematics.tanD(myInput); ...

The list of SEAMCATs math functions can be found here and the actual implementation of theese can be found here.

Problems ?

Q: Why do I get an error telling me the class file has a wrong version ?
A: If you get an error like the one below, it is because you are trying to compile the plugin using a java-version earlier than 1.5.0. Check your PATH environment variable if there is a reference to a directory containing another javac.exe. Alternatively use full path to the javac compiler when compiling the plugin. cannot access org.seamcat.mathematics.Mathematics 
 bad class file: ..libseamcat_needed_for_plugin.jar(org/seamcat/mathematics/Mathematics.class) 
 class file has wrong version 49.0, should be 48.0

Q: Why do I get an "The specified class failed to load" when trying to add a new plugin ?
A: Check your %HOME_DIR%seamcatseamcat.log file. If you see an "java.lang.NoClassDefFoundError: org/seamcat/model/plugin/PostProcessingPlugin" error message, then you have forgotten to copy the seamcat_needed_for_plugins.jar file to the plugins dir. Copy this file and restart Seamcat.

Q: Why do I get an Unknown command error when trying to compile my plugin ?
A: You didn't add %JAVA_HOME%bin to your PATH environment variable.

Q: Can I use post processing plugins in batch mode?
A: The batch interface itself does not provide ways to setup post processing plugins, however, it is possible to load a previously saved workspace which has been configured with one or more post processing plugins.

Q: Can I use post processing plugins when sending my Workspace to a remote server?
A: Yes you can - but ONLY if the plugins that you use has already been installed on the server.