It’s groovy baby …

Wouldn’t it be nice to access the API of an own RCP by using a script? Hence, adding script support to an own RCP application, that’s groovy. Indeed, Groovy is a good choice for such a purpose. Hence, I thought it’s easy to install the Groovy-Eclipse 3.7 plug-in into my own RCP OpenChrom from the marketplace … and boooom, that’s it. It wasn’t. After 3 days of handling with missing JDT and PDE dependencies, I surrendered. Despite of that, the Groovy-Eclipse plug-in is a great choice for the Eclipse IDE, but it didn’t worked for me. Anyhow, I got it working with a simple RCP test case, but the next issue was to access the API of the enclosing RCP. Again, there were problems accessing the OSGi bundles. Why on earth, there must be a solution. It was really getting ungroovy now. But after staying off the project some days, I thought about testing an embedded version of the Groovy Shell. That was the solution.

First of all, the latest Groovy binary release is needed:
http://dist.groovy.codehaus.org/distributions/groovy-binary-2.0.2.zip

It includes a folder called “embeddable” which contains the groovy redistributable “groovy-all-2.0.2.jar”. Please consider, Groovy is licensed under the Apache License, Version 2.0. Please also take care of the ANTLR, ASM, CLI, JSR223 licenses. They are stored in the downloaded zip file. The jar file needs to be included in the classpath of the plug-in. Use the “Runtime” tab of the MANIFEST.MF file.

Groovy-Jar-Classpath

A handler can be used to load groovy scripts inside the RCP application.

try {
	GroovyShell groovyShell = new GroovyShell();
	File file = new File("parse-chromatogram.groovy");
	Script script = groovyShell.parse(file);
	script.run();
} catch(CompilationFailedException e) {
	System.out.println(e);
} catch(IOException e) {
	System.out.println(e);
}

The Groovy Shell can be used now to execute Groovy script files, for example a file to parse a chromatogram: parse-chromatogram.groovy.

/*
 * Select a chromatogram file.
 * Print the TIC value of each scan.
 */
File file = new File("Chromatogram1.CDF")
IProgressMonitor monitor = new NullProgressMonitor()
IChromatogramImportConverterProcessingInfo processingInfo
try {
	/*
	 * Try to process the chromatogram.
	 */
	processingInfo = ChromatogramConverter.convert(file, monitor)
	IChromatogram chromatogram = processingInfo.getChromatogram()
	int numberOfScans = chromatogram.getNumberOfScans()
	for(int i = 1; i <= numberOfScans; i++) {
		ISupplierMassSpectrum scan = chromatogram.getScan(i)
		println("SCAN [" + i + "] - TIC: " + scan.getTotalSignal())
	}
} catch(TypeCastException e) {
	/*
	 * Print error messages.
	 */
	List<IProcessingMessage> messages = processingInfo.getMessages()
	for(int i = 0; i < messages.size(); i++) {
		IProcessingMessage message = messages.get(i)
		println(message.getDescription() + "\t" + message.getMessage())
	}
}

But which classes and bundles are accessible by the the Groovy script? It depends on the referenced packages by the executing plug-in. In this case, I’ve added all necessary bundles of Eclipse and OpenChrom to use the scripts in a variety of situations. Use the “Dependencies” tab of the MANIFEST.MF file to add plug-ins whose classes shall be accessible by the Groovy script.

Plugin-Dependencies

That’s it! This feature will be available in the next release of OpenChrom end of October 2012, version 0.7.0 “Nernst”. The next step will be to offer a support for editing groovy files within OpenChrom. But so far, it’s a great step forward. The users of OpenChrom have the chance to create their own evaluation scripts now.

That’s groovy baby …

Posted in Uncategorized | Leave a comment

Creating heatmaps using SWT XY Graph

I just discovered a brilliant library SWT XYGraph to create heatmaps. The following image is an example of a chromatogram heatmap. Mass spectrometric chromatograms are three-dimensional data sets containing scans (Y), mass fragments (X) and intensities (Z).

Chromatogram Heatmap

This is a short example of how to use the SWT XYGraph library. Get the libraries and include them in your project:

org.csstudio.swt.widgets_2.0.1.201207141617.jar
org.csstudio.swt.xygraph_2.0.1.201207141617.jar

The libraries are published under the EPL v1.0 license.

This is the code I’ve used to create a chromatogram heatmap:

LightweightSystem lightweightSystem = new LightweightSystem(canvas);
lightweightSystem.getRootFigure().setBackgroundColor(display.getSystemColor(SWT.COLOR_WHITE));
IntensityGraphFigure intensityGraphFigure = new IntensityGraphFigure();
intensityGraphFigure.setForegroundColor(display.getSystemColor(SWT.COLOR_BLACK));
intensityGraphFigure.getXAxis().setTitle("m/z");
intensityGraphFigure.getYAxis().setTitle("scan");
...
int dataHeight = stopScan - startScan + 1; // y -> scans
int dataWidth = stopIon - startIon + 1; // x -> m/z values
/**
 * Parse the data
 */
float maxIntensity = 0;
float[] heatmapData = new float[dataWidth * dataHeight * 2];
/**
 * Y-Axis: Scans
 */
for(int scan = startScan; scan <= stopScan; scan++) {
	int xScan = scan - startScan; // xScan is zero based, scan maybe not
	IExtractedIonSignal extractedIonSignal;
	try {
		extractedIonSignal = extractedIonSignals.getExtractedIonSignal(scan);
		for(int ion = startIon; ion <= stopIon; ion++) {
			/**
			 * X-Axis: m/z intensities
			 */
			int xIon = ion - startIon; // xIon is zero based, ion maybe not
			float abundance = extractedIonSignal.getAbundance(ion);
			if(abundance > maxIntensity) {
				maxIntensity = abundance;
			}
			heatmapData[xScan * dataWidth + xIon] = abundance;
		}
	} catch(NoExtractedIonSignalStoredException e) {
		logger.warn(e);
	}
}
/**
 * Set the ranges and min/max values.
 */
intensityGraphFigure.getXAxis().setRange(new Range(startIon, stopIon));
intensityGraphFigure.getYAxis().setRange(new Range(stopScan, startScan));
intensityGraphFigure.setMin(0); // Intensity
intensityGraphFigure.setMax(maxIntensity / 1000.0d); // Intensity
intensityGraphFigure.setDataHeight(dataHeight);
intensityGraphFigure.setDataWidth(dataWidth);
intensityGraphFigure.setColorMap(new ColorMap(PredefinedColorMap.JET, true, true));
/**
 * Set the heatmap data
 */
lightweightSystem.setContents(intensityGraphFigure);
intensityGraphFigure.setDataArray(heatmapData);

The chromatogram heatmap feature will be available in the next OpenChrom release, version 0.7.0 “Nernst”, scheduled for end of October 2012.

EclipseCon Europe 2012

Posted in Uncategorized | 3 Comments

From 0 to 10000 in two years!

OpenChrom has reached the mark of 10000 downloads today, since its start 2 years ago!

openchrom 10000 downloads

Posted in Uncategorized | Leave a comment

OpenChrom 0.6.0 “Synge” released – the open source chromatography and mass spectrometry software

I proudly announce the official OpenChrom release version 0.6.0 “Synge”.
Note, that Java 7 is required. The documentation is in progress and will be extended. Several improvements are available now, e.g.:

  • Varian *.SMS converter (experimental)
  • Basic mzXML support for the 3.1 and 3.2 specifications
  • Peak identification batch support for peaks modelled by PARAFAC/MCR algorithms
  • Chromatogram database plug-in
  • PDF and ZIP chromatogram export capabilities
  • Export chromatogram peaks to *.msp format, which can be loaded by the NIST-DB
  • Better process feedback
  • Completely reworked marketplace
  • Full update functionality

Go there, get it:
http://www.openchrom.net/main/content/downloads.php

Posted in Uncategorized | Leave a comment

Using Wuala as a private GIT repository

I’ve used an USB stick to store my private GIT repositories for a while. Then it happened, the stick crashed. Oh no. Still, I had several backups of its content, but it was definitively time to search for an alternative. Meanwhile, a lot of web storage providers offer free space limited accounts. These are for example DropBox, Box or if you have an own server ownCloud. Anyhow, ownCloud seems to be a good alternative, especially regarding security issues. But you need an own server with at least PHP 5.3 version. Mine has only PHP 5.2, d’oh. In any case, I’ve found another service, called Wuala. It offers 2 GB free storage, which is quite enough for hosting private source code. Furthermore, data encryption will be carried out on the client. Hence, it is a more secure method than DropBox unless you use a week password. Moreover, the files are hosted on servers in Switzerland, Germany and/or France which is another big advantage.

Wuala

To create an Wuala account, you’ll only need a user name, an email address and the appropriate client for your device. We are now ready to create a private GIT repository, after installing the software and creating the account. Use the command line and create a bare GIT repository. This repository is now ready to be cloned.

:~$cd WualaDrive/Username
:~/WualaDrive/Username$mkdir GIT-PROJECT
:~/WualaDrive/Username$cd GIT-PROJECT
:~/WualaDrive/Username/GIT-PROJECT$git init
:~/WualaDrive/Username/GIT-PROJECT$git config --bool core.bare true
:~/WualaDrive/Username/GIT-PROJECT$git config user.name "Your name"
:~/WualaDrive/Username/GIT-PROJECT$git config user.email "Your email"
:~/WualaDrive/Username/GIT-PROJECT$cd ~
:~$git clone ~/WualaDrive/Username/GIT-PROJECT

I also had a look at Assembla, which seems to fit my needs to share private GIT projects with other developers of OpenChrom. Therefore, here’s a list of private GIT repository vendors that offer limited accounts free of charge:

Assembla
Bitbucket
Bettercodes
Projectlocker
Unfuddle

In my mind, there are quite good possibilities to store private source code without paying a bunch of money today.

Posted in Uncategorized | 2 Comments

Congrats to all Community Award Winners 2012! and 1000 thanks to all my users

OpenChrom has gone beyond the 1000 downloads per month limit this month! Incredible! Fantastic! Overwhelming!

OpenChrom 1000+ downloads in March 2012

Posted in Uncategorized | Leave a comment

Updating RCP applications – don’t “use osgi.configuration.cascaded=true”

Recently, I’ve thought that I’ve understood how the update mechanism of an RCP application works. I don’t. Though the articles from Lars Vogel and Ralf Ebert about updating RCP applications were a great help, something went completely wrong with OpenChrom. And I definitively had no clue where to start searching. Everything worked fine updating additional installed plug-ins, but the base RCP couldn’t be updated. Each time the update mechanism told me, that no updates are available.

No updates were found

Anyhow, the update sites are accessible in the same way it works for the plug-ins. No success. Then I exported the product and uploaded the created metadata repository on my server. After adding the update site “http://www.openchrom.net/main/repositories/0.6.x/repository” to the list of “Available Software Sites” and running the update again, I’ve got the following error message.

Only one of the following can be installed at once

Aha, the first hint “Only one of the following can be installed at once“. It brought me to the Bug 322344 which led me to the assumption, that it has something to do with the “Multi-user install” settings. Hence, I had a look at the Eclipse runtime options and the settings used in OpenChrom’s options file “openchrom.ini”.

...
-Dosgi.install.area.readOnly
-Dosgi.configuration.area=@user.home/.openchrom/0.6.0/OpenChrom/configuration
-Dosgi.instance.area.default=@user.home/OpenChrom/workspace
...

I’ve used a distinct configuration area to allow installations of user-specific plug-ins, see Eclipse multi-user installs. It works fine for such a purpose but not for updating the base RCP. Time to tinker with these settings. Finally, I’ve found a setting that works under Windows, Linux and MAC OS X.

...
-Dosgi.install.area.readOnly
-Dosgi.instance.area=@user.home/OpenChrom/workspace
-Dosgi.user.area=@user.home/.openchrom/0.6.0/Settings
...

It works so far and I’ve learned to not use “osgi.configuration.cascaded=true” if the base RCP application shall be updatable. But honestly, I’d really like to fully understand how multi-user install configurations and the p2 update mechanism are working. Is there maybe someone, who has a good tutorial or white-paper?

Posted in Uncategorized | 7 Comments

Own Marketplace Server – Part II

I’ve described how to setup an own marketplace server with PHP and MySQL earlier, watch the post. Today, we’ll have a look at the requirements of an automated resolution of dependencies. First of all, it’s necessary to add the parameter (selfContained=”false”) to the marketplace catalog extension point. The p2 mechanism will calculate and fetch the required bundles automatically from now on.

<extension
	point="org.eclipse.epp.mpc.ui.catalog">
	<catalog
		description="Install new plug-ins from the OpenChrom marketplace."
		icon="icons/logo_32x32.png"
		label="OpenChrom Marketplace"
		url="http://www.openchrom.net/"
		selfContained="false">
	</catalog>
</extension>

But how does p2 know where to fetch the required dependencies? It can’t know unless you specify the repositories to look at (Available Software Sites).

Available Software Sites Empty

The first approach would be to add each repository manually, but it’s a blunt work. Moreover, do you really want that your customers add these repositories by themselves? That’s why we need an automated solution. And here is such a solution. Additional repositories can be added by using the following code:

private void addProvisioningRepositories() {

	URI uri;
	Map<String, String> map = new HashMap<String, String>();
	map.put("Indigo", "http://download.eclipse.org/releases/indigo");
	map.put("The Eclipse Project Updates", "http://download.eclipse.org/eclipse/updates/3.7");
	map.put("Eclipse Orbit", "http://download.eclipse.org/tools/orbit/downloads/drops/S20120123151124/repository");
	map.put("OpenChrom", "http://www.openchrom.net/main/updates/0.6.x");
	map.put("OpenChrom Plug-ins", "http://www.openchrom.net/plugins/updates/0.6.x");
	map.put("OpenChrom Third Party Libraries", "http://www.openchrom.net/plugins/thirdpartylibraries/updates/0.6.x");
	map.put("OpenChrom Keys", "http://www.openchrom.net/plugins/keys/updates/0.6.x");
	/**
	 * Add the repository locations.
	 */
	ProvisioningSession session = ProvisioningUI.getDefaultUI().getSession();
	RepositoryTracker repositoryTracker = ProvisioningUI.getDefaultUI().getRepositoryTracker();
	try {
		for(Map.Entry<String, String> entry : map.entrySet()) {
			uri = new URI(entry.getValue());
			repositoryTracker.addRepository(uri, entry.getKey(), session);
		}
	} catch(URISyntaxException e) {
		logger.warn(e);
	}
}

Voilà, it works.

Available Software Sites Filled

But the repositories shall be added only once. No problem by using the platform preferences.

private void addProvisioningRepositoriesOnDemand() {

	IPreferenceStore preferences = PlatformUI.getPreferenceStore();
	/**
	 * Returns false if there is no such value (on startup)
	 */
	if(!preferences.getBoolean(P2_UPDATE_REPOSITORIES_STILL_ADDED)) {
		/**
		 * Add additional p2 repositories.
		 */
		addProvisioningRepositories();
		preferences.setValue(P2_UPDATE_REPOSITORIES_STILL_ADDED, true);
	}
}

I’ve added the code in the “postWindowOpen()” of the “ApplicationWorkbenchWindowAdvisor” class. It works fine and my customers are happy too.

Posted in Uncategorized | 3 Comments

OpenChrom version 0.6.0 “Synge” preview has been released!

I proudly announce the availability of the preview release 0.6.0 “Synge”.
Several improvements are included, e.g.:

  • Varian *.SMS converter
  • Basic mzXML support for the 3.1 and 3.2 specifications
  • Peak identification batch support
  • Better process feedback
  • Completely reworked marketplace
  • No need to install the “Keys” plug-in previously, before installing additional plug-ins
  • Full update functionality

Go there, get it:
http://www.openchrom.net/main/content/downloads.php

The final release will be published end of April 2012.

Posted in Uncategorized | 1 Comment

Own Marketplace Server using PHP/MySQL

First of all, thanks to Tom Seidel who is the project lead of Remus and provides an open source marketplace server. The marketplace server uses J2EE and needs a Jetty or another application server.

But why on earth do we need another marketplace server solution?

Simple question, simple answer. I’m not familiar with J2EE. Furthermore, it’s more expensive to rent a root server for running a Jetty than using a hosted standard server with PHP and MySQL. Anyhow, the marketplace server from Tom works well and I used it for a while, but honestly, I’ve already planned get rid of my noisy and power consuming home server which I’ve used instead of an expensive hosted root server.

Homer Application Server

Hence, I thought by myself, isn’t it possible to create a marketplace server utilizing PHP and MySQL, in respect to the point that I still have a hosted standard server with http://www.openchrom.net?

After studying the marketplace server specification, it was obvious what to do. The query results will be returned in XML format. No problem for PHP.

header("Content-Type: text/xml; charset=utf-8");
$doc = new DOMDocument;
$root = $doc->createElement('marketplace');
$rootNode = $doc->appendChild($root);
...
echo $doc->saveXML();

All queries use a distinct syntax to retrieve the marketplace results. This query for example (http://marketplace.eclipse.org/featured/api/p) is used to retrieve a list of featured plug-ins from the Eclipse Marketplace. The GET paramters are variable and depend on the used Eclipse version. Hence, is it possible to redirect the query to a PHP file which itself returns the requested XML file? Yes it is, if you’re using an Apache with activated “mod_rewrite” option. Well, most of the providers do have the “mod_rewrite” option activated. Simply create a “.htaccess” file and route the marketplace requests to distinct PHP files.

RewriteEngine on
RewriteRule ^featured/api/p$ http://www.openchrom.net/marketplace/featured.php?%{QUERY_STRING}
...

An own marketplace can be included in a RCP solution by using the extension point “org.eclipse.epp.mpc.ui.catalog”. I’ve included my own marketplace for OpenChrom in the following way:

<extension
	point="org.eclipse.epp.mpc.ui.catalog">
	<catalog
		description="Install new plug-ins from the OpenChrom marketplace."
		icon="icons/logo_32x32.png"
		label="OpenChrom Marketplace"
		url="http://www.openchrom.net/">
	</catalog>
</extension>

Last but not least, a check shows that it works fine! Moreover, it’s now possible to return only those plug-ins that match to the specific OpenChrom version and used operating system.

OpenChrom Marketplace Client

That’s it. In the next article, I’ll describe how to fetch dependent plug-ins automatically.

Posted in Uncategorized | 3 Comments