diff --git a/src/cell.cpp b/src/cell.cpp
index a6986f0673ca05827ee89493aca2230ec16cec30..8fdd1bb6e0f55cdfa2a3c7ea6632e0fdee74bba6 100644
--- a/src/cell.cpp
+++ b/src/cell.cpp
@@ -195,5 +195,41 @@ std::vector<int> const& cell::segment_parents() const
     return parents_;
 }
 
+// Rough and ready comparison of two cells.
+// We don't use an operator== because equality of two cells is open to
+// interpretation. For example, it is possible to have two viable representations
+// of a cell: with and without location information for the cables.
+//
+// Checks that two cells have the same
+//  - number and type of segments
+//  - volume and area properties of each segment
+//  - number of compartments in each segment
+bool cell_basic_equality(cell const& lhs, cell const& rhs)
+{
+    if(lhs.num_segments() != rhs.num_segments()) {
+        return false;
+    }
+    if(lhs.segment_parents() != rhs.segment_parents()) {
+        return false;
+    }
+    for(auto i=0; i<lhs.num_segments(); ++i) {
+        // a quick and dirty test
+        auto& l = *lhs.segment(i);
+        auto& r = *rhs.segment(i);
+
+        if(l.kind() != r.kind()) return false;
+        if(l.area() != r.area()) return false;
+        if(l.volume() != r.volume()) return false;
+        if(l.as_cable()) {
+            if(   l.as_cable()->num_compartments()
+               != r.as_cable()->num_compartments())
+            {
+                return false;
+            }
+        }
+    }
+    return true;
+}
+
 } // namespace mc
 } // namespace nest
diff --git a/src/cell.hpp b/src/cell.hpp
index ba5f9b6bff227231cbb4f46e27dd2af4ff2943ce..fece134947041d705564008e54be61ce93d50f60 100644
--- a/src/cell.hpp
+++ b/src/cell.hpp
@@ -123,6 +123,12 @@ class cell {
     std::vector<std::pair<segment_location, i_clamp>> stimulii_;
 };
 
+// Checks that two cells have the same
+//  - number and type of segments
+//  - volume and area properties of each segment
+//  - number of compartments in each segment
+bool cell_basic_equality(cell const& lhs, cell const& rhs);
+
 // create a cable by forwarding cable construction parameters provided by the user
 template <typename... Args>
 cable_segment* cell::add_cable(cell::index_type parent, Args ...args)
diff --git a/src/segment.hpp b/src/segment.hpp
index fd1d8ded6101cc8e9834b9062df3da97de5cbc8c..decb0cdd88665c421cf159b8d7f49e4f91e03f0f 100644
--- a/src/segment.hpp
+++ b/src/segment.hpp
@@ -76,6 +76,16 @@ class segment {
         return nullptr;
     }
 
+    virtual const cable_segment* as_cable() const
+    {
+        return nullptr;
+    }
+
+    virtual const soma_segment* as_soma() const
+    {
+        return nullptr;
+    }
+
     virtual bool is_placeholder() const
     {
         return false;
@@ -230,6 +240,11 @@ class soma_segment : public segment
         return this;
     }
 
+    const soma_segment* as_soma() const override
+    {
+        return this;
+    }
+
     /// soma has one and one only compartments
     int num_compartments() const override
     {
@@ -359,6 +374,11 @@ class cable_segment : public segment
         return this;
     }
 
+    const cable_segment* as_cable() const override
+    {
+        return this;
+    }
+
     int num_compartments() const override
     {
         return num_compartments_;
diff --git a/src/util.hpp b/src/util.hpp
index 706ab7da5a17d493823b8c74d1f18fa6b4a9efaf..afa029ff9cfcba65258473875003c00f58c3d16b 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -45,6 +45,21 @@ std::ostream& print(std::ostream &o, std::vector<T>const& v)
     return o;
 }
 
+template <typename T>
+bool operator ==(const std::vector<T>& lhs, const std::vector<T>& rhs)
+{
+    if(lhs.size() != rhs.size()) {
+        return false;
+    }
+    return std::equal(lhs.begin(), lhs.end(), rhs.begin());
+}
+
+template <typename T>
+bool operator !=(const std::vector<T>& lhs, const std::vector<T>& rhs)
+{
+    return !(lhs==rhs);
+}
+
 namespace nest {
 namespace mc {
 namespace util {
diff --git a/tests/test_swcio.cpp b/tests/test_swcio.cpp
index 679260d656c9c7964f0eea599951c371886123f4..6968fd432a89842023807c8ed0ffb2ca8140b231 100644
--- a/tests/test_swcio.cpp
+++ b/tests/test_swcio.cpp
@@ -487,3 +487,31 @@ TEST(swc_io, cell_construction)
                   cell.cable(3)->radius(0));
     }
 }
+
+// check that simple ball and stick model with one dendrite attached to a soma
+// which is used in the validation tests can be loaded from file and matches
+// the one generated with the C++ interface
+TEST(swc_parser, from_file_ball_and_stick)
+{
+    auto fname = "../data/ball_and_stick.swc";
+    std::ifstream fid(fname);
+    if(!fid.is_open()) {
+        std::cerr << "unable to open file " << fname << "... skipping test\n";
+        return;
+    }
+
+    // read the file into a cell object
+    auto cell = nest::mc::io::swc_read_cell(fid);
+
+    // verify that the correct number of nodes was read
+    EXPECT_EQ(cell.num_segments(), 2);
+    EXPECT_EQ(cell.num_compartments(), 2u);
+
+    // make an equivalent cell via C++ interface
+    nest::mc::cell local_cell;
+    local_cell.add_soma(6.30785);
+    local_cell.add_cable(0, nest::mc::segmentKind::dendrite, 0.5, 0.5, 200);
+
+    EXPECT_TRUE(nest::mc::cell_basic_equality(local_cell, cell));
+}
+