Index: src/Makefile.am
===================================================================
--- src/Makefile.am	(revision 93d120bdcc6b28744fc18c21d8ef1e744eaa9f1e)
+++ src/Makefile.am	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -1,4 +1,4 @@
-SOURCE = atom.cpp bond.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp graph.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp
-HEADER = atom.hpp bond.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp graph.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp
+SOURCE = analysis_correlation.cpp atom.cpp bond.cpp boundary.cpp config.cpp element.cpp ellipsoid.cpp graph.cpp helpers.cpp leastsquaremin.cpp linkedcell.cpp memoryusageobserver.cpp moleculelist.cpp molecule.cpp molecule_dynamics.cpp molecule_fragmentation.cpp molecule_geometry.cpp molecule_graph.cpp molecule_pointcloud.cpp parser.cpp periodentafel.cpp tesselation.cpp tesselationhelpers.cpp vector.cpp verbose.cpp
+HEADER = analysis_correlation.hpp atom.hpp bond.hpp boundary.hpp config.hpp defs.hpp element.hpp ellipsoid.hpp graph.hpp helpers.hpp leastsquaremin.hpp linkedcell.hpp lists.hpp memoryallocator.hpp memoryusageobserver.hpp molecule.hpp molecule_template.hpp parser.hpp periodentafel.hpp stackclass.hpp tesselation.hpp tesselationhelpers.hpp vector.hpp verbose.hpp
 
 BOOST_LIB = $(BOOST_LDFLAGS) $(BOOST_MPL_LIB)
Index: src/analysis_correlation.cpp
===================================================================
--- src/analysis_correlation.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
+++ src/analysis_correlation.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -0,0 +1,143 @@
+/*
+ * analysis.cpp
+ *
+ *  Created on: Oct 13, 2009
+ *      Author: heber
+ */
+
+#include <iostream>
+
+#include "analysis_correlation.hpp"
+#include "element.hpp"
+#include "molecule.hpp"
+#include "tesselation.hpp"
+#include "tesselationhelpers.hpp"
+#include "vector.hpp"
+
+
+/** Calculates the pair correlation between given elements.
+ * Note given element order is unimportant (i.e. g(Si, O) === g(O, Si))
+ * \param *out output stream for debugging
+ * \param *mol molecule with atoms
+ * \param *type1 first element or NULL (if any element)
+ * \param *type2 second element or NULL (if any element)
+ * \return Map of doubles with values the pair of the two atoms.
+ */
+PairCorrelationMap *PairCorrelation( ofstream *out, molecule *mol, element *type1, element *type2 )
+{
+  PairCorrelationMap *outmap = NULL;
+  double distance = 0.;
+
+  if ((mol == NULL)) {
+    cout << "No molecule given." << endl;
+    return outmap;
+  }
+  outmap = new PairCorrelationMap;
+  atom *Walker = mol->start;
+  while (Walker->next != mol->end) {
+    Walker = Walker->next;
+    if ((type1 == NULL) || (Walker->type == type1)) {
+      atom *OtherWalker = mol->start;
+      while (OtherWalker->next != mol->end) { // only go up to Walker
+        OtherWalker = OtherWalker->next;
+        if (Walker->nr < OtherWalker->nr)
+          if ((type2 == NULL) || (OtherWalker->type == type2)) {
+            distance = Walker->node->Distance(OtherWalker->node);
+            //cout << "Inserting " << *Walker << " and " << *OtherWalker << endl;
+            outmap->insert ( pair<double, pair <atom *, atom*> > (distance, pair<atom *, atom*> (Walker, OtherWalker) ) );
+          }
+      }
+    }
+  }
+
+  return outmap;
+};
+
+/** Calculates the distance (pair) correlation between a given element and a point.
+ * \param *out output stream for debugging
+ * \param *mol molecule with atoms
+ * \param *type element or NULL (if any element)
+ * \param *point vector to the correlation point
+ * \return Map of dobules with values as pairs of atom and the vector
+ */
+CorrelationToPointMap *CorrelationToPoint( ofstream *out, molecule *mol, element *type, Vector *point )
+{
+  CorrelationToPointMap *outmap = NULL;
+  double distance = 0.;
+
+  if ((mol == NULL)) {
+    cout << "No molecule given." << endl;
+    return outmap;
+  }
+  outmap = new CorrelationToPointMap;
+  atom *Walker = mol->start;
+  while (Walker->next != mol->end) {
+    Walker = Walker->next;
+    if ((type == NULL) || (Walker->type == type)) {
+      distance = Walker->node->Distance(point);
+      outmap->insert ( pair<double, pair<atom *, Vector*> >(distance, pair<atom *, Vector*> (Walker, point) ) );
+    }
+  }
+
+  return outmap;
+};
+
+/** Calculates the distance (pair) correlation between a given element and a surface.
+ * \param *out output stream for debugging
+ * \param *mol molecule with atoms
+ * \param *type element or NULL (if any element)
+ * \param *Surface pointer to Tesselation class surface
+ * \param *LC LinkedCell structure to quickly find neighbouring atoms
+ * \return Map of doubles with values as pairs of atom and the BoundaryTriangleSet that's closest
+ */
+CorrelationToSurfaceMap *CorrelationToSurface( ofstream *out, molecule *mol, element *type, Tesselation *Surface, LinkedCell *LC )
+{
+
+  CorrelationToSurfaceMap *outmap = NULL;
+  double distance = 0.;
+  class BoundaryTriangleSet *triangle = NULL;
+  Vector centroid;
+
+  if ((Surface == NULL) || (LC == NULL) || (mol == NULL)) {
+    cout << "No Tesselation, no LinkedCell or no molecule given." << endl;
+    return outmap;
+  }
+  outmap = new CorrelationToSurfaceMap;
+  atom *Walker = mol->start;
+  while (Walker->next != mol->end) {
+    Walker = Walker->next;
+    if ((type == NULL) || (Walker->type == type)) {
+      triangle = Surface->FindClosestTriangleToPoint(out, Walker->node, LC );
+      if (triangle != NULL) {
+        distance = DistanceToTrianglePlane(out, Walker->node, triangle);
+        outmap->insert ( pair<double, pair<atom *, BoundaryTriangleSet*> >(distance, pair<atom *, BoundaryTriangleSet*> (Walker, triangle) ) );
+      }
+    }
+  }
+
+  return outmap;
+};
+
+/** Returns the start of the bin for a given value.
+ * \param value value whose bin to look for
+ * \param BinWidth width of bin
+ * \param BinStart first bin
+ */
+double GetBin ( double value, double BinWidth, double BinStart )
+{
+  double bin =(double) (floor((value - BinStart)/BinWidth));
+  return (bin*BinWidth+BinStart);
+};
+
+
+/** Prints correlation (double, int) pairs to file.
+ * \param *file file to write to
+ * \param *map map to write
+ */
+void OutputCorrelation( ofstream *file, BinPairMap *map )
+{
+  *file << "# BinStart\tCount" << endl;
+  for (BinPairMap::iterator runner = map->begin(); runner != map->end(); ++runner) {
+    *file << runner->first << "\t" << runner->second << endl;
+  }
+};
Index: src/analysis_correlation.hpp
===================================================================
--- src/analysis_correlation.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
+++ src/analysis_correlation.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -0,0 +1,117 @@
+/*
+ * analysis.hpp
+ *
+ *  Created on: Oct 13, 2009
+ *      Author: heber
+ */
+
+#ifndef ANALYSIS_HPP_
+#define ANALYSIS_HPP_
+
+using namespace std;
+
+/*********************************************** includes ***********************************/
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <fstream>
+
+// STL headers
+#include <map>
+
+#include "defs.hpp"
+
+#include "atom.hpp"
+
+/****************************************** forward declarations *****************************/
+
+class BoundaryTriangleSet;
+class element;
+class LinkedCell;
+class molecule;
+class Tesselation;
+class Vector;
+
+/********************************************** definitions *********************************/
+
+typedef multimap<double, pair<atom *, atom *> > PairCorrelationMap;
+typedef multimap<double, pair<atom *, Vector *> > CorrelationToPointMap;
+typedef multimap<double, pair<atom *, BoundaryTriangleSet *> > CorrelationToSurfaceMap;
+typedef map<double, int> BinPairMap;
+
+/********************************************** declarations *******************************/
+
+PairCorrelationMap *PairCorrelation( ofstream *out, molecule *mol, element *type1, element *type2 );
+CorrelationToPointMap *CorrelationToPoint( ofstream *out, molecule *mol, element *type, Vector *point );
+CorrelationToSurfaceMap *CorrelationToSurface( ofstream *out, molecule *mol, element *type, Tesselation *Surface, LinkedCell *LC );
+double GetBin ( double value, double BinWidth, double BinStart );
+void OutputCorrelation( ofstream *file, BinPairMap *map );
+
+
+/** Searches for lowest and highest value in a given map of doubles.
+ * \param *map map of doubles to scan
+ * \param &min minimum on return
+ * \param &max maximum on return
+ */
+template <typename T> void GetMinMax ( T *map, double &min, double &max)
+{
+  min = 0.;
+  max = 0.;
+  bool FirstMinFound = false;
+  bool FirstMaxFound = false;
+
+  for (typename T::iterator runner = map->begin(); runner != map->end(); ++runner) {
+    if ((min > runner->first) || (!FirstMinFound)) {
+      min = runner->first;
+      FirstMinFound = true;
+    }
+    if ((max < runner->first) || (!FirstMaxFound)) {
+      max = runner->first;
+      FirstMaxFound = true;
+    }
+  }
+};
+
+/** Puts given correlation data into bins of given size (histogramming).
+ * Note that BinStart and BinEnd are desired to fill the complete range, even where Bins are zero. If this is
+ * not desired, give equal BinStart and BinEnd and the map will contain only Bins where the count is one or greater.
+ * Also note that the range is given inclusive, i.e. [ BinStart, BinEnd ].
+ * \param *out output stream for debugging
+ * \param *map map of doubles to count
+ * \param BinWidth desired width of the binds
+ * \param BinStart first bin
+ * \param BinEnd last bin
+ * \return Map of doubles (the bins) with counts as values
+ */
+template <typename T> BinPairMap *BinData ( ofstream *out,  T *map, double BinWidth, double BinStart, double BinEnd )
+{
+  BinPairMap *outmap = new BinPairMap;
+  double bin = 0.;
+  double start = 0.;
+  double end = 0.;
+  pair <BinPairMap::iterator, bool > BinPairMapInserter;
+
+  if (BinStart == BinEnd) { // if same, find range ourselves
+    GetMinMax( map, start, end);
+  } else { // if not, initialise range to zero
+    start = BinStart;
+    end = BinEnd;
+    for (double runner = start; runner <= end; runner += BinWidth)
+      outmap->insert( pair<double, int> (runner, 0.) );
+  }
+
+  for (typename T::iterator runner = map->begin(); runner != map->end(); ++runner) {
+    bin = GetBin (runner->first, BinWidth, start);
+    BinPairMapInserter = outmap->insert ( pair<double, int> (bin, 1) );
+    if (!BinPairMapInserter.second) {  // bin already present, increase
+      BinPairMapInserter.first->second += 1;
+    }
+  }
+
+  return outmap;
+};
+
+#endif /* ANALYSIS_HPP_ */
Index: src/tesselationhelpers.cpp
===================================================================
--- src/tesselationhelpers.cpp	(revision 93d120bdcc6b28744fc18c21d8ef1e744eaa9f1e)
+++ src/tesselationhelpers.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -679,4 +679,19 @@
 };
 
+/** Returns the distance to the plane defined by \a *triangle
+ * \param *out output stream for debugging
+ * \param *x Vector to calculate distance to
+ * \param *triangle triangle defining plane
+ * \return distance between \a *x and plane defined by \a *triangle, -1 - if something went wrong
+ */
+double DistanceToTrianglePlane(ofstream *out, Vector *x, BoundaryTriangleSet *triangle)
+{
+  double distance = 0.;
+  if (x == NULL) {
+    return -1;
+  }
+  distance = x->DistanceToPlane(out, &triangle->NormalVector, triangle->endpoints[0]->node->node);
+  return distance;
+};
 
 /** Creates the objects in a VRML file.
Index: src/tesselationhelpers.hpp
===================================================================
--- src/tesselationhelpers.hpp	(revision 93d120bdcc6b28744fc18c21d8ef1e744eaa9f1e)
+++ src/tesselationhelpers.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -68,4 +68,5 @@
 void WriteVrmlFile(ofstream *out, ofstream *vrmlfile, class Tesselation *Tess, PointCloud *cloud);
 void CalculateConcavityPerBoundaryPoint(ofstream *out, class Tesselation *TesselStruct);
+double DistanceToTrianglePlane(ofstream *out, Vector *x, BoundaryTriangleSet *triangle);
 
 bool CheckListOfBaselines(ofstream *out, Tesselation *TesselStruct);
Index: src/unittests/AnalysisCorrelationToPointUnitTest.cpp
===================================================================
--- src/unittests/AnalysisCorrelationToPointUnitTest.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
+++ src/unittests/AnalysisCorrelationToPointUnitTest.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -0,0 +1,154 @@
+/*
+ * AnalysisCorrelationToPointUnitTest.cpp
+ *
+ *  Created on: Oct 13, 2009
+ *      Author: heber
+ */
+
+using namespace std;
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "analysis_correlation.hpp"
+#include "AnalysisCorrelationToPointUnitTest.hpp"
+
+#include "atom.hpp"
+#include "boundary.hpp"
+#include "element.hpp"
+#include "molecule.hpp"
+#include "linkedcell.hpp"
+#include "periodentafel.hpp"
+#include "tesselation.hpp"
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( AnalysisCorrelationToPointUnitTest );
+
+void AnalysisCorrelationToPointUnitTest::setUp()
+{
+  atom *Walker = NULL;
+
+  // init private all pointers to zero
+  TestMolecule = NULL;
+  hydrogen = NULL;
+  tafel = NULL;
+  pointmap = NULL;
+  binmap = NULL;
+  point = NULL;
+
+  // construct element
+  hydrogen = new element;
+  hydrogen->Z = 1;
+  strcpy(hydrogen->name, "hydrogen");
+  hydrogen->symbol[0] = 'H';
+
+  // construct periodentafel
+  tafel = new periodentafel;
+  tafel->AddElement(hydrogen);
+
+  // construct molecule (tetraeder of hydrogens)
+  TestMolecule = new molecule(tafel);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(1., 0., 1. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(0., 1., 1. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(1., 1., 0. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(0., 0., 0. );
+  TestMolecule->AddAtom(Walker);
+
+  // check that TestMolecule was correctly constructed
+  CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 );
+
+  // init point
+  point = new Vector(1.,1.,1.);
+
+  // init maps
+  pointmap = CorrelationToPoint( (ofstream *)&cout, TestMolecule, hydrogen, point );
+  binmap = NULL;
+
+};
+
+
+void AnalysisCorrelationToPointUnitTest::tearDown()
+{
+  if (pointmap != NULL)
+    delete(pointmap);
+  if (binmap != NULL)
+    delete(binmap);
+
+  // remove
+  delete(TestMolecule);
+  // note that all the atoms are cleaned by TestMolecule
+  delete(point);
+  delete(tafel);
+  // note that element is cleaned by periodentafel
+};
+
+void AnalysisCorrelationToPointUnitTest::CorrelationToPointTest()
+{
+  // do the pair correlation
+  CPPUNIT_ASSERT( pointmap != NULL );
+  CPPUNIT_ASSERT_EQUAL( (size_t)4, pointmap->size() );
+
+};
+
+void AnalysisCorrelationToPointUnitTest::CorrelationToPointBinNoRangeTest()
+{
+  BinPairMap::iterator tester;
+  // put pair correlation into bins and check with no range
+  binmap = BinData( (ofstream *)&cout, pointmap, 0.5, 0., 0. );
+  CPPUNIT_ASSERT_EQUAL( (size_t)2, binmap->size() );
+  //OutputCorrelation ( (ofstream *)&cout, binmap );
+  tester = binmap->begin();
+  CPPUNIT_ASSERT_EQUAL( 1., tester->first );
+  CPPUNIT_ASSERT_EQUAL( 3, tester->second );
+
+};
+
+void AnalysisCorrelationToPointUnitTest::CorrelationToPointBinRangeTest()
+{
+  BinPairMap::iterator tester;
+  // ... and check with [0., 2.] range
+  binmap = BinData( (ofstream *)&cout, pointmap, 0.5, 0., 2. );
+  CPPUNIT_ASSERT_EQUAL( (size_t)5, binmap->size() );
+  //OutputCorrelation ( (ofstream *)&cout, binmap );
+  tester = binmap->begin();
+  CPPUNIT_ASSERT_EQUAL( 0., tester->first );
+  tester = binmap->find(1.);
+  CPPUNIT_ASSERT_EQUAL( 1., tester->first );
+  CPPUNIT_ASSERT_EQUAL( 3, tester->second );
+
+};
+
+/********************************************** Main routine **************************************/
+
+int main(int argc, char **argv)
+{
+  // Get the top level suite from the registry
+  CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+  // Adds the test to the list of test to run
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( suite );
+
+  // Change the default outputter to a compiler error format outputter
+  runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
+                                                       std::cerr ) );
+  // Run the tests.
+  bool wasSucessful = runner.run();
+
+  // Return error code 1 if the one of test failed.
+  return wasSucessful ? 0 : 1;
+};
Index: src/unittests/AnalysisCorrelationToPointUnitTest.hpp
===================================================================
--- src/unittests/AnalysisCorrelationToPointUnitTest.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
+++ src/unittests/AnalysisCorrelationToPointUnitTest.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -0,0 +1,48 @@
+/*
+ * AnalysisCorrelationToPointUnitTest.hpp
+ *
+ *  Created on: Oct 13, 2009
+ *      Author: heber
+ */
+
+#ifndef ANALYSISCORRELATIONTOPOINTUNITTEST_HPP_
+#define ANALYSISCORRELATIONTOPOINTUNITTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class element;
+class molecule;
+class LinkedCell;
+class periodentafel;
+class Tesselation;
+class Vector;
+
+/********************************************** Test classes **************************************/
+
+class AnalysisCorrelationToPointUnitTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( AnalysisCorrelationToPointUnitTest ) ;
+    CPPUNIT_TEST ( CorrelationToPointTest );
+    CPPUNIT_TEST ( CorrelationToPointBinNoRangeTest );
+    CPPUNIT_TEST ( CorrelationToPointBinRangeTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void CorrelationToPointTest();
+      void CorrelationToPointBinNoRangeTest();
+      void CorrelationToPointBinRangeTest();
+
+private:
+
+      molecule *TestMolecule;
+      element *hydrogen;
+      periodentafel *tafel;
+
+      CorrelationToPointMap *pointmap;
+      BinPairMap *binmap;
+      Vector *point;
+};
+
+#endif /* ANALYSISCORRELATIONTOPOINTUNITTEST_HPP_ */
Index: src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp
===================================================================
--- src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
+++ src/unittests/AnalysisCorrelationToSurfaceUnitTest.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -0,0 +1,163 @@
+/*
+ * AnalysisCorrelationToSurfaceUnitTest.cpp
+ *
+ *  Created on: Oct 13, 2009
+ *      Author: heber
+ */
+
+using namespace std;
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "analysis_correlation.hpp"
+#include "AnalysisCorrelationToSurfaceUnitTest.hpp"
+
+#include "atom.hpp"
+#include "boundary.hpp"
+#include "element.hpp"
+#include "molecule.hpp"
+#include "linkedcell.hpp"
+#include "periodentafel.hpp"
+#include "tesselation.hpp"
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( AnalysisCorrelationToSurfaceUnitTest );
+
+void AnalysisCorrelationToSurfaceUnitTest::setUp()
+{
+  atom *Walker = NULL;
+
+  // init private all pointers to zero
+  TestMolecule = NULL;
+  hydrogen = NULL;
+  tafel = NULL;
+  surfacemap = NULL;
+  binmap = NULL;
+  Surface = NULL;
+  LC = NULL;
+
+
+  // construct element
+  hydrogen = new element;
+  hydrogen->Z = 1;
+  strcpy(hydrogen->name, "hydrogen");
+  hydrogen->symbol[0] = 'H';
+
+  // construct periodentafel
+  tafel = new periodentafel;
+  tafel->AddElement(hydrogen);
+
+  // construct molecule (tetraeder of hydrogens)
+  TestMolecule = new molecule(tafel);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(1., 0., 1. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(0., 1., 1. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(1., 1., 0. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(0., 0., 0. );
+  TestMolecule->AddAtom(Walker);
+
+  // check that TestMolecule was correctly constructed
+  CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 );
+
+  // init tesselation and linked cell
+  Surface = new Tesselation;
+  TestMolecule->TesselStruct = Surface;
+  FindNonConvexBorder((ofstream *)&cout, TestMolecule, LC, 2.5, NULL);
+  LC = new LinkedCell(TestMolecule, 5.);
+  CPPUNIT_ASSERT_EQUAL( (size_t)4, Surface->PointsOnBoundary.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)6, Surface->LinesOnBoundary.size() );
+  CPPUNIT_ASSERT_EQUAL( (size_t)4, Surface->TrianglesOnBoundary.size() );
+
+  // init maps
+  surfacemap = CorrelationToSurface( (ofstream *)&cout, TestMolecule, hydrogen, Surface, LC );
+  binmap = NULL;
+
+};
+
+
+void AnalysisCorrelationToSurfaceUnitTest::tearDown()
+{
+  if (surfacemap != NULL)
+    delete(surfacemap);
+  if (binmap != NULL)
+    delete(binmap);
+
+  // remove
+  delete(TestMolecule);
+  // note that Surface and all the atoms are cleaned by TestMolecule
+  delete(LC);
+  delete(tafel);
+  // note that element is cleaned by periodentafel
+};
+
+
+void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceTest()
+{
+  // do the pair correlation
+  CPPUNIT_ASSERT( surfacemap != NULL );
+  CPPUNIT_ASSERT_EQUAL( (size_t)4, surfacemap->size() );
+};
+
+void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceBinNoRangeTest()
+{
+  BinPairMap::iterator tester;
+  // put pair correlation into bins and check with no range
+  binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 0. );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, binmap->size() );
+  //OutputCorrelation ( (ofstream *)&cout, binmap );
+  tester = binmap->begin();
+  CPPUNIT_ASSERT_EQUAL( 0., tester->first );
+  CPPUNIT_ASSERT_EQUAL( 4, tester->second );
+
+};
+
+void AnalysisCorrelationToSurfaceUnitTest::CorrelationToSurfaceBinRangeTest()
+{
+  BinPairMap::iterator tester;
+  // ... and check with [0., 2.] range
+  binmap = BinData( (ofstream *)&cout, surfacemap, 0.5, 0., 2. );
+  CPPUNIT_ASSERT_EQUAL( (size_t)5, binmap->size() );
+  //OutputCorrelation ( (ofstream *)&cout, binmap );
+  tester = binmap->begin();
+  CPPUNIT_ASSERT_EQUAL( 0., tester->first );
+  CPPUNIT_ASSERT_EQUAL( 4, tester->second );
+  tester = binmap->find(1.);
+  CPPUNIT_ASSERT_EQUAL( 1., tester->first );
+  CPPUNIT_ASSERT_EQUAL( 0, tester->second );
+
+};
+
+/********************************************** Main routine **************************************/
+
+int main(int argc, char **argv)
+{
+  // Get the top level suite from the registry
+  CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+  // Adds the test to the list of test to run
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( suite );
+
+  // Change the default outputter to a compiler error format outputter
+  runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
+                                                       std::cerr ) );
+  // Run the tests.
+  bool wasSucessful = runner.run();
+
+  // Return error code 1 if the one of test failed.
+  return wasSucessful ? 0 : 1;
+};
Index: src/unittests/AnalysisCorrelationToSurfaceUnitTest.hpp
===================================================================
--- src/unittests/AnalysisCorrelationToSurfaceUnitTest.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
+++ src/unittests/AnalysisCorrelationToSurfaceUnitTest.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -0,0 +1,48 @@
+/*
+ * AnalysisCorrelationToSurfaceUnitTest.hpp
+ *
+ *  Created on: Oct 13, 2009
+ *      Author: heber
+ */
+
+#ifndef ANALYSISCORRELATIONTOSURFACEUNITTEST_HPP_
+#define ANALYSISCORRELATIONTOSURFACEUNITTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class element;
+class molecule;
+class LinkedCell;
+class periodentafel;
+class Tesselation;
+
+/********************************************** Test classes **************************************/
+
+class AnalysisCorrelationToSurfaceUnitTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( AnalysisCorrelationToSurfaceUnitTest ) ;
+    CPPUNIT_TEST ( CorrelationToSurfaceTest );
+    CPPUNIT_TEST ( CorrelationToSurfaceBinNoRangeTest );
+    CPPUNIT_TEST ( CorrelationToSurfaceBinRangeTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void CorrelationToSurfaceTest();
+      void CorrelationToSurfaceBinNoRangeTest();
+      void CorrelationToSurfaceBinRangeTest();
+
+private:
+
+      molecule *TestMolecule;
+      element *hydrogen;
+      periodentafel *tafel;
+
+      CorrelationToSurfaceMap *surfacemap;
+      BinPairMap *binmap;
+      Tesselation *Surface;
+      LinkedCell *LC;
+};
+
+#endif /* ANALYSISCORRELATIONTOSURFACEUNITTEST_HPP_ */
Index: src/unittests/AnalysisPairCorrelationUnitTest.cpp
===================================================================
--- src/unittests/AnalysisPairCorrelationUnitTest.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
+++ src/unittests/AnalysisPairCorrelationUnitTest.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -0,0 +1,147 @@
+/*
+ * AnalysisPairCorrelationUnitTest.cpp
+ *
+ *  Created on: Oct 13, 2009
+ *      Author: heber
+ */
+
+using namespace std;
+
+#include <cppunit/CompilerOutputter.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+
+#include "analysis_correlation.hpp"
+#include "AnalysisPairCorrelationUnitTest.hpp"
+
+#include "atom.hpp"
+#include "boundary.hpp"
+#include "element.hpp"
+#include "molecule.hpp"
+#include "linkedcell.hpp"
+#include "periodentafel.hpp"
+#include "tesselation.hpp"
+
+/********************************************** Test classes **************************************/
+
+// Registers the fixture into the 'registry'
+CPPUNIT_TEST_SUITE_REGISTRATION( AnalysisPairCorrelationUnitTest );
+
+
+void AnalysisPairCorrelationUnitTest::setUp()
+{
+  atom *Walker = NULL;
+
+  // init private all pointers to zero
+  TestMolecule = NULL;
+  hydrogen = NULL;
+  tafel = NULL;
+  correlationmap = NULL;
+  binmap = NULL;
+
+  // construct element
+  hydrogen = new element;
+  hydrogen->Z = 1;
+  strcpy(hydrogen->name, "hydrogen");
+  hydrogen->symbol[0] = 'H';
+
+  // construct periodentafel
+  tafel = new periodentafel;
+  tafel->AddElement(hydrogen);
+
+  // construct molecule (tetraeder of hydrogens)
+  TestMolecule = new molecule(tafel);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(1., 0., 1. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(0., 1., 1. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(1., 1., 0. );
+  TestMolecule->AddAtom(Walker);
+  Walker = new atom();
+  Walker->type = hydrogen;
+  Walker->node->Init(0., 0., 0. );
+  TestMolecule->AddAtom(Walker);
+
+  // check that TestMolecule was correctly constructed
+  CPPUNIT_ASSERT_EQUAL( TestMolecule->AtomCount, 4 );
+
+  // init maps
+  correlationmap = PairCorrelation( (ofstream *)&cout, TestMolecule, hydrogen, hydrogen );
+  binmap = NULL;
+
+};
+
+
+void AnalysisPairCorrelationUnitTest::tearDown()
+{
+  if (correlationmap != NULL)
+    delete(correlationmap);
+  if (binmap != NULL)
+    delete(binmap);
+
+  // remove
+  delete(TestMolecule);
+  // note that all the atoms are cleaned by TestMolecule
+  delete(tafel);
+  // note that element is cleaned by periodentafel
+};
+
+void AnalysisPairCorrelationUnitTest::PairCorrelationTest()
+{
+  // do the pair correlation
+  CPPUNIT_ASSERT( correlationmap != NULL );
+  CPPUNIT_ASSERT_EQUAL( (size_t)6, correlationmap->size() );
+};
+
+void AnalysisPairCorrelationUnitTest::PairCorrelationBinNoRangeTest()
+{
+  BinPairMap::iterator tester;
+  // put pair correlation into bins and check with no range
+  binmap = BinData( (ofstream *)&cout, correlationmap, 0.5, 0., 0. );
+  CPPUNIT_ASSERT_EQUAL( (size_t)1, binmap->size() );
+  //OutputCorrelation ( (ofstream *)&cout, binmap );
+  tester = binmap->begin();
+  CPPUNIT_ASSERT_EQUAL( sqrt(2.), tester->first );
+  CPPUNIT_ASSERT_EQUAL( 6, tester->second );
+};
+
+void AnalysisPairCorrelationUnitTest::PairCorrelationBinRangeTest()
+{
+  BinPairMap::iterator tester;
+  // ... and check with [0., 2.] range
+  binmap = BinData( (ofstream *)&cout, correlationmap, 0.5, 0., 2. );
+  CPPUNIT_ASSERT_EQUAL( (size_t)5, binmap->size() );
+  //OutputCorrelation ( (ofstream *)&cout, binmap );
+  tester = binmap->begin();
+  CPPUNIT_ASSERT_EQUAL( 0., tester->first );
+  tester = binmap->find(1.);
+  CPPUNIT_ASSERT_EQUAL( 1., tester->first );
+  CPPUNIT_ASSERT_EQUAL( 6, tester->second );
+};
+
+/********************************************** Main routine **************************************/
+
+int main(int argc, char **argv)
+{
+  // Get the top level suite from the registry
+  CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+  // Adds the test to the list of test to run
+  CppUnit::TextUi::TestRunner runner;
+  runner.addTest( suite );
+
+  // Change the default outputter to a compiler error format outputter
+  runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
+                                                       std::cerr ) );
+  // Run the tests.
+  bool wasSucessful = runner.run();
+
+  // Return error code 1 if the one of test failed.
+  return wasSucessful ? 0 : 1;
+};
Index: src/unittests/AnalysisPairCorrelationUnitTest.hpp
===================================================================
--- src/unittests/AnalysisPairCorrelationUnitTest.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
+++ src/unittests/AnalysisPairCorrelationUnitTest.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -0,0 +1,47 @@
+/*
+ * AnalysisPairCorrelationUnitTest.hpp
+ *
+ *  Created on: Oct 13, 2009
+ *      Author: heber
+ */
+
+#ifndef ANALYSISPAIRCORRELATIONUNITTEST_HPP_
+#define ANALYSISPAIRCORRELATIONUNITTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+class element;
+class molecule;
+class LinkedCell;
+class periodentafel;
+class Tesselation;
+class Vector;
+
+/********************************************** Test classes **************************************/
+
+class AnalysisPairCorrelationUnitTest : public CppUnit::TestFixture
+{
+    CPPUNIT_TEST_SUITE( AnalysisPairCorrelationUnitTest ) ;
+    CPPUNIT_TEST ( PairCorrelationTest );
+    CPPUNIT_TEST ( PairCorrelationBinNoRangeTest );
+    CPPUNIT_TEST ( PairCorrelationBinRangeTest );
+    CPPUNIT_TEST_SUITE_END();
+
+public:
+      void setUp();
+      void tearDown();
+      void PairCorrelationTest();
+      void PairCorrelationBinNoRangeTest();
+      void PairCorrelationBinRangeTest();
+
+private:
+
+      molecule *TestMolecule;
+      element *hydrogen;
+      periodentafel *tafel;
+
+      PairCorrelationMap *correlationmap;
+      BinPairMap *binmap;
+};
+
+#endif /* ANALYSISPAIRCORRELATIONUNITTEST_HPP_ */
Index: src/unittests/Makefile.am
===================================================================
--- src/unittests/Makefile.am	(revision 93d120bdcc6b28744fc18c21d8ef1e744eaa9f1e)
+++ src/unittests/Makefile.am	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -1,14 +1,28 @@
 INCLUDES = -I$(top_srcdir)/src
 
-noinst_PROGRAMS =  ActOnAllTest MemoryAllocatorUnitTest MemoryUsageObserverUnitTest VectorUnitTest
+noinst_PROGRAMS =  ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest MemoryAllocatorUnitTest MemoryUsageObserverUnitTest VectorUnitTest
 
-TESTS = ActOnAllTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest VectorUnitTest
+TESTS = ActOnAllUnitTest AnalysisCorrelationToPointUnitTest AnalysisCorrelationToSurfaceUnitTest AnalysisPairCorrelationUnitTest MemoryUsageObserverUnitTest MemoryAllocatorUnitTest VectorUnitTest
 check_PROGRAMS = $(TESTS)
 
-ActOnAllTest_SOURCES = ActOnAllTest.hpp ActOnAllUnitTest.cpp ActOnAllUnitTest.hpp memoryallocator.hpp
-ActOnAllTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
-ActOnAllTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-ActOnAllTest_LDADD = ../libmolecuilder.a
+ActOnAllUnitTest_SOURCES = ActOnAllTest.hpp ActOnAllUnitTest.cpp ActOnAllUnitTest.hpp memoryallocator.hpp
+ActOnAllUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
+ActOnAllUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
+ActOnAllUnitTest_LDADD = ../libmolecuilder.a
 
+AnalysisCorrelationToPointUnitTest_SOURCES = analysis_correlation.hpp AnalysisCorrelationToPointUnitTest.cpp AnalysisCorrelationToPointUnitTest.hpp
+AnalysisCorrelationToPointUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
+AnalysisCorrelationToPointUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
+AnalysisCorrelationToPointUnitTest_LDADD = ../libmolecuilder.a
+
+AnalysisCorrelationToSurfaceUnitTest_SOURCES = analysis_correlation.hpp AnalysisCorrelationToSurfaceUnitTest.cpp AnalysisCorrelationToSurfaceUnitTest.hpp
+AnalysisCorrelationToSurfaceUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
+AnalysisCorrelationToSurfaceUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
+AnalysisCorrelationToSurfaceUnitTest_LDADD = ../libmolecuilder.a
+
+AnalysisPairCorrelationUnitTest_SOURCES = analysis_correlation.hpp AnalysisPairCorrelationUnitTest.cpp AnalysisPairCorrelationUnitTest.hpp
+AnalysisPairCorrelationUnitTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
+AnalysisPairCorrelationUnitTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
+AnalysisPairCorrelationUnitTest_LDADD = ../libmolecuilder.a
 
 VectorUnitTest_SOURCES = defs.hpp helpers.hpp leastsquaremin.hpp memoryallocator.hpp memoryusageobserver.hpp vectorunittest.cpp vectorunittest.hpp vector.hpp verbose.hpp 
Index: src/vector.cpp
===================================================================
--- src/vector.cpp	(revision 93d120bdcc6b28744fc18c21d8ef1e744eaa9f1e)
+++ src/vector.cpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -256,4 +256,26 @@
     return false;
   }
+};
+
+/** Calculates the minimum distance of this vector to the plane.
+ * \param *out output stream for debugging
+ * \param *PlaneNormal normal of plane
+ * \param *PlaneOffset offset of plane
+ * \return distance to plane
+ */
+double Vector::DistanceToPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset)
+{
+  Vector temp;
+
+  // first create part that is orthonormal to PlaneNormal with withdraw
+  temp.CopyVector(this);
+  temp.SubtractVector(PlaneOffset);
+  temp.MakeNormalVector(PlaneNormal);
+  temp.Scale(-1.);
+  // then add connecting vector from plane to point
+  temp.AddVector(this);
+  temp.SubtractVector(PlaneOffset);
+
+  return temp.Norm();
 };
 
Index: src/vector.hpp
===================================================================
--- src/vector.hpp	(revision 93d120bdcc6b28744fc18c21d8ef1e744eaa9f1e)
+++ src/vector.hpp	(revision c4d4dfcf2b2eb619122842838b8a34fed1b278e5)
@@ -31,4 +31,5 @@
   double Distance(const Vector *y) const;
   double DistanceSquared(const Vector *y) const;
+  double DistanceToPlane(ofstream *out, Vector *PlaneNormal, Vector *PlaneOffset);
   double PeriodicDistance(const Vector *y, const double *cell_size) const;
   double PeriodicDistanceSquared(const Vector *y, const double *cell_size) const;
