.NET Examples

Table of Contents

  1. Supported .NET Frameworks
  2. Setting up a project using Marvin
  3. Setting up a project using JChem
  4. API documentation
  5. Marvin and new molecule representation examples with the NEW ChemAxon .NET API
  6. JChem Examples with the NEW ChemAxon .NET API
  7. Workflow components (model-view-controller) in ChemAxon .NET API

1. Supported .NET Frameworks

.NET Framework 3.5 or above is supported. Please note that .NET Compact Framework and .NET 4 Client Profile are not supported.

2. Setting up a project using Marvin

  1. Download and install (extract) the .NET package here.
  2. Add the following dll files as references to your project:
  3. Recommended initialization step for Marvin:
    No other initialization needed.
    Except only if you would like to run Marvin Sketcher as a stand alone application then please use: ChemAxon.JChem.Common.Init();
  4. Redistribution of the package can be done by:
    • reusing our msm modules in msi installer package of you application (dlls in GAC)
    • running our msi installer before installation of your application (dlls in GAC)
    • local deployment without GAC, in your application folder all dlls have to be copied (copylocal = true)

3. Setting up a project using JChem

  1. Download and install the .NET package here.
  2. Add the following dll files as references to your project (like in these examples):
    The following third party dll files may also be required (depending on usage):
    Database drivers
    jtds-1.2.2.dll - Library used to interact with MS SQL 2005 database.
    mysql-connector-java-bin.dll - Library used to interact with MySQL database.
    ojdbc14.dll - Library used to interact with Oracle database.
    postgresql-8.3-604.jdbc4.dll - Library used to interact with PostgreSQL database.
  3. Redistribution of the package can be done by:
    • reusing our msm modules in msi installer package of you application (dlls in GAC)
    • running our msi installer before installation of your application (dlls in GAC)
    • local deployment without GAC, in your application folder all dlls have to be copied (copylocal = true)

4. API documentation

The NEW ChemAxon .NET API documentation is available in PPT format while all programming areas are not covered (in 6.3).

The JChem .NET API documentation is available in CHM and online.

5. Marvin and new molecule representation examples with the NEW ChemAxon .NET API

Full examples with Visual Studio 2010 solutions are provided by the installer package.

5.a, Integrating MarvinSketch into a .NET Winforms application

    Example gives a short demo how to visualize structures or molecule data in .NET Windows forms controls.
    Supported controls are the following: read-only viewer control, in-place editor control and editor dialog and molecule grid control.

Viewer control
var benzeneData = new MoleculeData("[O-]C1=CC=CC=C1", MoleculeFormat.SMILES);
var benzeneMolecule = MainFactory.Chemistry.CreateMolecule(benzeneData);
// viewer
var viewer = new MarvinViewControl();
viewer.Molecule = "C1=CC=CC=C1";
viewer = new MarvinViewControl();
viewer.MoleculeData = benzeneData;
viewer = new MarvinViewControl();
viewer.MoleculeObject = benzeneMolecule.Transformations.AddHAtoms();

Editor control for in-place editing
// editor
var editor = new MarvinEditorControl();
editor.Molecule = "C1=CC=CC=C1";
editor.MoleculeFormat = MoleculeFormat.SMILES.GetDescription().CodeName;
editor = new MarvinEditorControl();
editor.MoleculeData = benzeneData;
editor = new MarvinEditorControl();
editor.MoleculeObject = benzeneMolecule.Transformations.AddHAtoms();

Editor dialog with YES/NO result
// sketcher form
IMoleculeEditorView view = new MarvinSketchForm();
view.MoleculeData = benzeneData;
if (view.ShowAsDialog() == DialogResponse.OK) {
Console.WriteLine("Molecule has been amended ...");
else {
Console.WriteLine("Editing cancelled ...");

Example code => View ShowMarvinSketch.cs

How to load controls (editor control/dialog) on a separate thread.
// start loading controls (editor) on a separate thread

// Button_Click event to Add structures
MarvinSketchForm editor = new MarvinSketchForm();
var result = editor.ShowAsDialog();

Grid view control for displaying list of structures
BindingList<BindableMolecule> list = new BindingList();
// Fill Data and Aromatize in one step
foreach (var mol in enumarator) {
list.Add(MainFactory.Chemistry.CreateBindableMolecule( mol.Transformations.Aromatize()));
// Visualization in Grid
MoleculeGridView gv = new MoleculeGridView();
// Settings
gv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
gv.MoleculeCellSize = new System.Drawing.Size(150, 150);
gv.AutoGenerateColumns = false;
// Binding
gv.DataSource = list;

Example code => SDF into Grid View.cs

Grid view control and DataTable
    This section shows how to set up a .NET DataTable object with data, in this case the molecule objects are retrieved e.g. from a database table.
    No ChemAxon specific code is needed for filling this object.
    The Data Grid View control has some molecule specific properties e.g. defining a formula column, adding molecule columns.
var benzeneMolecule = MainFactory.Chemistry.CreateMolecule("C1=CC=CC=C1", MoleculeFormat.Unknown);

DataTable tbl = new DataTable();

// columns
DataColumn colMolData = new DataColumn("Structure", typeof(string));
DataColumn colMolFormula = new DataColumn("Formula", typeof(string));
DataColumn colMolWeight = new DataColumn("Weight", typeof(float));

tbl.Columns.Add(colMolData); tbl.Columns.Add(colMolFormula); tbl.Columns.Add(colMolWeight);

// Data Fill
tbl.LoadDataRow(new object[] { benzeneMolecule.MoleculeData.StringData, benzeneMolecule.Formula, benzeneMolecule.Mass }, true);
tbl.LoadDataRow(new object[] { benzeneMolecule.Transformations.Aromatize().MoleculeData.StringData, benzeneMolecule.Transformations.Aromatize().Formula, benzeneMolecule.Transformations.Aromatize().Mass }, true);

// Grid visualization
MoleculeGridView gv = new MoleculeGridView ();
// settings gv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
gv. MoleculeCellSize = new System.Drawing.Size(150, 150);
// Binding
gv. DataSource = tbl;
gv. MoleculeColumns.Add ("Structure");
gv. FormulaColumn = "Formula";

5.b, How to use IO modules in third party applications

    Simple examples showing how to import structures from files, how to save molecule lists into files with different file formats.
    The examples below show how single or multiple structures are available for clipboard manipulations, introduction to the new ChemAxon clipboard formats.
    OLE data embedding, and OLE content on the clipboard is also demonstrated in the following example section.

Process files with molecule content
IFileHandler fileHandler = MainFactory.IO.OpenFile(@"molecules.mrv");
IEnumerable<IJChemMolecule> molecules = fileHandler.Read();

foreach (IJChemMolecule molecule in molecules)

IFileHandler fileHandler = MainFactory.IO.OpenFile(@"molecules.mrv");

var newMolecules = new List<IJChemMolecule>();

Example code => FileExample.cs

Working with structures on the Clipboard
var molecules = new List<IJChemMolecule>();

IClipboardHandler clipboard = MainFactory.IO.OpenClipboard();

IEnumerable<IJChemMolecule> molecules;
bool isMoleculeOnClipboard = clipboard.PasteFrom(out molecules);

How to copy and paste molecule and other assay data in the same work unit with ChemAxon .NET API

IClipboardHandler clipboard = MainFactory.IO.OpenClipboard();

IClipboardTable clipboardData = clipboard.CreateClipboardTable(3, 2);
clipboardData[0, 0].Data.SetValue(MainFactory.Chemistry.CreateMolecule("benzene"));
clipboardData[1,1].Data.SetValue("Comment 1");
clipboardData[2, 0].Data.SetValue(MainFactory.Chemistry.CreateMolecule("methylpropane"));
clipboardData[0, 1].Data.SetValue("Comment 2");
clipboardData[1,0].Data.SetValue("Comment 3");
clipboardData[2, 1].Data.SetValue(MainFactory.Chemistry.CreateMolecule("hexane"));

IClipboardTable clipboardData;
bool isMixedDataOnClipboard = clipboard.PasteFrom(out clipboardData);

Example code => ClipboardExample.cs

OLE objects in IO workflows
IOleHandler ole = MainFactory.IO.OpenOle();

if (ole.IsMarvinOleDocumentOnClipboard())
{ IJChemMolecule molecule;
ole.PasteFrom(out molecule);

Example code => OLEExample.cs

5.c, Molecule rendering and Image generation (for WEB/Browser based applications)

    The simplest way of rendering a molecule with ChemAxon .NET libraries:
var benzeneData = new MoleculeData("C1=CC=CC=C1", MoleculeFormat.Unknown);
var benzeneMolecule = MainFactory.Chemistry.CreateMolecule(benzeneData);
// simple benzene rendering with default rendering settings
var image = benzeneMolecule.Renderer.RenderToImage(ImageFormat.Emf);

// changing the settings and reredering of the same molecule
benzeneMolecule.Renderer.Settings.DrawingInfo.Size = new Size(120, 120);
benzeneMolecule.Renderer.Settings.DrawingInfo.StructureDrawingSettings.WireThickness = 0.23;
var image = benzeneMolecule.Renderer.RenderToImage(ImageFormat.Emf);

// changing the background color and rendering the molecule as bitmap
benzeneMolecule.Renderer.Settings.DrawingInfo.Transparent = false;
benzeneMolecule.Renderer.Settings.DrawingInfo.BackgroundColor = Color.LightGreen;
var image = benzeneMolecule.Renderer.RenderToImage(ImageFormat.Bmp);

Example code => View MoleculeImage.cs

5.d, Molecule and Representations

    Example below shows how a single molecule can be represented in different molecule formats.
    How a molecule can be serialized and represented in a complex format (molecule data) and deserialized back from it simply using Chemistry factory.
// simple representations => returning value Simple Representation MoleculeData
string molString = benzeneMolecule.Representations.Represent(MoleculeFormat.MOL).StringData;
Console.WriteLine("MOL: " + molString);
string mrvString = benzeneMolecule.Representations.Represent(MoleculeFormat.MRV).StringData;
Console.WriteLine("MRV: " + mrvString);
byte[] cdxBinary = benzeneMolecule.Representations.Represent(MoleculeFormat.CDX).BinaryData;

// aggregated representations => returning Multiple Representation MoleculeData
var aggregatedDescriptor = new MultipleMoleculeRepresentation(MoleculeFormat.MRV).Add(CompressionFormat.GZIP).Add(EncodingFormat.BASE64);
var multipleMoleculeData = benzeneMolecule.Representations.Represent(aggregatedDescriptor);

// read back multiple representation
benzeneMolecule2 = MainFactory.Chemistry.CreateMolecule(multipleMoleculeData);

5.e, Molecule and Calculations, working with Calculated molecules

    Example below shows what calculated properties a molecule can expose.
    What further calculations are available through the molecule interface, how to render a new calculated molecule
// Calculated values
var chargeValue = benzeneMolecule.Calculations.GetCharge(5);
var logPValue = benzeneMolecule.Calculations.logP;
// Calculated molecules
var logPMolecule = benzeneMolecule.Calculations.GetlogPMolecule();

var view = new MarvinViewControl();
view.MoleculeObject = logPMolecule;
ShowMoleculeControl(view, "Calculated Molecules 1.");

5.f, Molecule and Transformations, working with Transformed molecules

    Example below shows how to apply transformations on molecules and how to render a newly transformed molecule
// Single actions
var view = new MarvinViewControl();
var view2 = new MarvinViewControl();
view.MoleculeObject = benzeneMolecule;
view2.MoleculeObject = benzeneMolecule.Transformations.Aromatize();

// Batch actions
// A, by action steps in a document
"<StandardizerConfiguration><Actions>" +
"<Aromatize ID=\"Aromatize\" Type=\"general\"/>" +
"<Transformation ID=\"Transform Nitro\" Structure=\"[O:3]=[N:1]=[O:2]>>[#8-:2][N+:1]=[O:3]\"/>" +
view = new MarvinViewControl();
view.MoleculeObject = benzeneMolecule.Transformations.Standardize(XML_CONFIGURATION);

// B, by Action steps manually
view = new MarvinViewControl();
view2 = new MarvinViewControl();
view.MoleculeObject = wrongBenzeneMolecule.Transformations.Validation.CheckStructure( "moleculecharge" );
view2.MoleculeObject = wrongBenzeneMolecule.Transformations.Validation.FixStructure( "moleculecharge" );

6. JChem Examples with the NEW ChemAxon .NET API

    The following section outlines how JChem library can be applied in .NET or ASP.NET integration. What areas are avilable in a middle layer code to manipulate backend.

6.a, How to manipulate molecules in the backend

    The next major section is about how to do some database specific operation with molecules including
    how to setup a database connection to have a gateway to certain database engines (like Oracle, MySQL, MS SQL, PostgreSQL).
    Once we have set up the connection the next step is to focus on the table where structures are located.
    The next step is to select one or more table and to start data manipulation actions.
    Our new API gives you facility to easily add/insert new structures into the database returning the new assigned identifier.
    Amend an existing molecule and restore it without extra effort.
    Delete structure from the table.
    All structure manipulations can be done in transaction otherwise the auto commitment takes place.

Connecting to a database
// DBType : MySQL, Oracle ... IConnectionInfo connection = MainFactory.Database.CreateConnection(host, port, database, user, pwd, databaseType);
IJChemDatabaseHandler dbHandler = MainFactory.Database.OpenJChem(connection);
Exploring tablespace and get database table
IEnumerable<IJChemTable> tables = database.GetTables();
return tables.First(table => table.Name == tableName);
Working with tables (inserting, updating, deleting molecules)
IJChemMolecule molecule = MainFactory.Chemistry.CreateMolecule("benzene");

//set values based on the data column
molecule.Properties.Add("DATE_COLUMN", DateTime.Now);
molecule.Properties.Add("VARCHAR_255_COLUMN", "Corporate ID");

JChemDBMolecule insertedMolecule;
table.Insert(molecule, out insertedMolecule);

//Update the molecule
IJChemMolecule newMolecule = MainFactory.Chemistry.CreateMolecule("methylpropane");

insertedMolecule.Properties.Add("DATE_COLUMN") = new DateTime(1992, 12, 11);
insertedMolecule.Properties.Add("VARCHAR_255_COLUMN") = "Modified corporate ID";
//or use
insertedMolecule.Properties["DATE_COLUMN"] = new DateTime(1992, 12, 11);
insertedMolecule.Properties["VARCHAR_255_COLUMN"] = "Modified corporate ID";


// Delete molecule

Searching for molecules
// Create a molecule first to be the query molecule e.g. in a substructure search
IJChemMolecule queryMolecule = MainFactory.Chemistry.CreateMolecule("Benzene");
// Create a filter criteria hanlder class and set the chemical filter options on it
IJChemMoleculeFilter moleculeFilter = MainFactory.Database.CreateJChemMoleculeFilter(queryMolecule);
moleculeFilter.SearchOption.InvertResults = false;
moleculeFilter.SearchOption.AbsoluteStereo = JChemAbsoluteStereoMatchingModes.AlwaysOn;

// Create conditions for the WHERE clause
IDBConditions dbConditions = MainFactory.Database.CreateDBConditions(ComparisonSqlOperatorType.Greater, new DateTime(1993,12,11), table["DATE_COLUMN"]);
// Extend the where clause with further crioterion
dbConditions.And(ComparisonSqlOperatorType.Less, DateTime.Now, table["DATE_COLUMN"]);

IEnumerable<JChemDBMolecule> molecules = table.GetMolecules(moleculeFilter, dbConditions);

Example code => DatabaseExample.cs   


6.b, How to use faster memory cache (db)

    Sometimes e.g. in a web service the need comes up to store structures but not in a database even in a simpler way in a cache.
    The key goal here is the faster storage and faster access of molecules without complicated infrastructure.
    In addition to read and write molecules from and into a storage, the infrastucture provides a search feature on the data as Filter does (see in the next Filter section).

Creating memory cache
var memoryTable = MainFactory.Database.OpenMemoryCache();
Adding molecules to memory cache

IJChemMolecule[] molecules = new IJChemMolecule[]{ MainFactory.Chemistry.CreateMolecule("methylpropane"), MainFactory.Chemistry.CreateMolecule("benzol") };
Searching for molecules
IJChemMolecule query = MainFactory.Chemistry.CreateMolecule("benzene");
bool isMatch = memoryTable.IsMatch(query);

Example code => MemoryCacheExample.cs   


6.c, How to manipulate molecules in the front end with JChem

    The next section is demonstrating what other chemical services the new ChemAxon .NET API includes in addition to creating and visualizing of molecules.
    If we have a backend service and we would like to create an "in-memory datacache/database" of molecules for chemical operations,
    Chemical Filtering and R-group Decomposition services are natively included in the Chemistry Service Factory.

Filtering molecules
// Create chemical filter for the list of target molecules, SearchMode can be AtomAtom or Fingerprint
IFilter filter = MainFactory.Chemistry.CreateFilter(targets, SearchMode.AtomAtom);
// Set the search type and other options affecting the result set of the filtering
filter.Options.SearchType = Base.Search.Options.JChemSearchTypes.Substructure;
filter.Options.ChargeMatchingOption = Base.Search.Options.JChemChargeMatchingModes.Exact;

// Create a query molecule for the search and simply run it
IJChemMolecule query = MainFactory.Chemistry.CreateMolecule("methane");
IEnumerable<IJChemMolecule> filterResult = filter.FindAll(query);

Example code => FilterExample.cs   

Decomposing R-group molecules
// Create chemical R-group decompoistion for the list of target molecules
IRGroupDecomposition rGroup = MainFactory.Chemistry.CreateRGroupDecomposition(targets);
// Set up options on R-group object e.g. the headers should be included with the fragments and so forth ...
rGroup.Options.IncludeHeader = true;
rGroup.Options.IncludeNonMatchingTarget = false;

It is easy to get the targets and the query molecule reusing the known controls

IJChemMolecule query = MainFactory.Chemistry.CreateMolecule("methane");

// Run the enumeration process with the query molecule
IEnumerable<IJChemMolecule[]> rGroupResult = rGroup.Decompose(query);
return rGroupResult;

The Result set can be displayed in a grid view control:

Example code => RGroupExample.cs   

7. Workflow components (model-view-controller) in ChemAxon .NET API

    The following section outlines what Workflow based reusable solutions we offer.... All workflows (behind the scene) consist of 3 layers.
    View, which represents the widget (forms, dialogs in most cases)
    Workflow model, which makes sure that the data capturing is done in the right way in order to run the workflow with
    Workflow controller/presenter, which controls and leads the workflow with dropping the proper widget, letting the model be filled properly and finally doing the main job

    In most cases the customer is allowed to change the widget part to their own one through an interface paramter, this will be demonstrated in the next sections ...

7.a, Molecule visualizations with workflow

    How to display molecules in a control has already been demonstrated above. Lets see now how it works by a controlled workflow

Display molecules

IJChemMolecule molecule = MainFactory.Chemistry.CreateMolecule("benzene");

// Show molecule simply through our predefined viewer dialog

// Setting up the custom molecule viewer implementing the IMoleculeViewer interface
IMoleculeViewer moleculeViewer = new CustomMoleculeViewer();
moleculeViewer.Caption = molecule.Formula;
moleculeViewer.DisplayHeight = 100;
moleculeViewer.DisplayWidth = 100;
moleculeViewer.Readonly = true;

// Show molecule thorugh a custom view form

MainFactory.Workflow.ShowMolecule(molecule, moleculeViewer);
Edit molecules
IJChemMolecule molecule = MainFactory.Chemistry.CreateMolecule("benzene");
IJChemMolecule newMolecule;

bool isMoleculeChanged = MainFactory.Workflow.EditMolecule(molecule, out newMolecule);

Example code => WorkflowExample.cs   

7.b, What is next in Workflows? ( we are focusing on but not ready with them yet )

    Visualization workflows might not highlight the main benefit of using complete workflows.
    But if we think of how to set RGroupDecomposition or Filter or Database queries/options,
    it is then not too too difficult to imagine how much work/effort might be to implement a widget for e.g.

    In the next versions of ChemAxon .NET API this is the area we would like to bring to library to safe time for coders. Areas and some screen shots you may see in next period:

Filtering molecules
Filter workflow starts with a filter dialog and ends with set of molecule objects matching with the filter criteria.

Decomposing R-group molecules
R-group decomposition workflow starts with specifying the scaffold molecule, which is the query structure for the R-group enumeration
In addtion to the query molecule the R-Group Decomposition options have to be set along with the target list of molecules the enumeration has to be run on.

Importing molecules from File
Importing from file is a workflow that contains two main steps inside. Browsing and selecting the target file and then selecting the necessary columns/molecule properties to be imported.

Importing molecules from Database
Importing from database is the most complicated workflow adding more two steps relatively to the Import from File workflow.

Selecting the file is replaced by the determining database connection and its type.
It is continued with specifiying the proper molecule table.

When it is done the next step is to capture the query data that might contain the structure and other additional chemical filter information.

Property selection from the underlying table is very similar to
the corresponding File Import step.

Which is followed by executing the query and
processing the hits in grid view control.


Copyright © 1998-2010 ChemAxon Ltd.    All rights reserved.