diff --git a/modules/gfx/pymod/export_color_ops.cc b/modules/gfx/pymod/export_color_ops.cc
index 492f5384e40e370fc5e51ea95ff4acbb3a22f773..4c5859c5fb447c9c2b913d20d92380d10de532a1 100644
--- a/modules/gfx/pymod/export_color_ops.cc
+++ b/modules/gfx/pymod/export_color_ops.cc
@@ -23,6 +23,7 @@
 #include <ost/gfx/color_ops/color_op.hh>
 #include <ost/gfx/color_ops/basic_gradient_color_op.hh>
 #include <ost/gfx/color_ops/by_element_color_op.hh>
+#include <ost/gfx/color_ops/by_chain_color_op.hh>
 #include <ost/gfx/color_ops/uniform_color_op.hh>
 #include <ost/gfx/color_ops/gradient_color_op.hh>
 #include <ost/gfx/color_ops/gradient_level_color_op.hh>
@@ -65,6 +66,12 @@ void export_ColorOps()
     .staticmethod("FromInfo")
   ;
 
+  class_<ByChainColorOp, bases<ColorOp> >("ByChainColorOp", init<>())
+    .def(init<const String&, int>())
+    .def("FromInfo",&ByChainColorOp::FromInfo)
+    .staticmethod("FromInfo")
+  ;
+
   class_<UniformColorOp, bases<ColorOp> >("UniformColorOp", init<const String&, const gfx::Color&>())
     .def(init<const String&, int, const gfx::Color&>())
     .def("SetColor",&UniformColorOp::SetColor)
diff --git a/modules/gfx/pymod/export_entity.cc b/modules/gfx/pymod/export_entity.cc
index 1807c2e2b9b4d65294a650259ed37d2966cd433a..23e341b04754d0d960e78747277459dba023d54c 100644
--- a/modules/gfx/pymod/export_entity.cc
+++ b/modules/gfx/pymod/export_entity.cc
@@ -147,6 +147,13 @@ void ent_apply_22(Entity* e, ByElementColorOp& beco){
   e->Apply(beco);
 }
 
+void ent_apply_31(Entity* e, ByChainColorOp& beco, bool store){
+  e->Apply(beco,store);
+}
+void ent_apply_32(Entity* e, ByChainColorOp& beco){
+  e->Apply(beco);
+}
+
 void ent_apply_41(Entity* e, EntityViewColorOp& evco, bool store){
   e->Apply(evco,store);
 }
@@ -263,6 +270,7 @@ void export_Entity()
     .def("PickAtom", &Entity::PickAtom)
     .def("PickBond", &Entity::PickBond)
     .def("ColorByElement",&Entity::ColorByElement)
+    .def("ColorByChain",&Entity::ColorByChain)
     .def("CleanColorOps", &Entity::CleanColorOps)
     .def("ReapplyColorOps", &Entity::ReapplyColorOps)
     .def("GetOptions", &Entity::GetOptions)
@@ -279,6 +287,8 @@ void export_Entity()
     .def("Apply",&ent_apply_12)
     .def("Apply",&ent_apply_21)
     .def("Apply",&ent_apply_22)
+    .def("Apply",&ent_apply_31)
+    .def("Apply",&ent_apply_32)
     .def("Apply",&ent_apply_41)
     .def("Apply",&ent_apply_42)
     .def("Apply",&ent_apply_51)
diff --git a/modules/gfx/src/CMakeLists.txt b/modules/gfx/src/CMakeLists.txt
index dce1c04fa0cb82f99c1878cb620e9cd2c5d1df4a..1f3569435d076ee65bbce91396eedb07453cb918 100644
--- a/modules/gfx/src/CMakeLists.txt
+++ b/modules/gfx/src/CMakeLists.txt
@@ -39,6 +39,7 @@ povray.hh
 set(OST_GFX_COLOR_OPS_HEADERS
 color_op.hh
 by_element_color_op.hh
+by_chain_color_op.hh
 uniform_color_op.hh
 gradient_color_op.hh
 entity_view_color_op.hh
@@ -108,6 +109,7 @@ material.cc
 povray.cc
 color_ops/color_op.cc
 color_ops/by_element_color_op.cc
+color_ops/by_chain_color_op.cc
 color_ops/uniform_color_op.cc
 color_ops/gradient_color_op.cc
 color_ops/entity_view_color_op.cc
diff --git a/modules/gfx/src/color_ops/by_chain_color_op.cc b/modules/gfx/src/color_ops/by_chain_color_op.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0bde2c8c147f34b208ec9910b94e52adfca5a071
--- /dev/null
+++ b/modules/gfx/src/color_ops/by_chain_color_op.cc
@@ -0,0 +1,89 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#include <math.h>
+
+#include "by_chain_color_op.hh"
+
+#include <ost/gfx/entity.hh>
+#include <ost/dyn_cast.hh>
+
+
+namespace ost { namespace gfx {
+
+ByChainColorOp::ByChainColorOp() : ColorOp(){this->init();}
+
+ByChainColorOp::ByChainColorOp(const String& selection) : ColorOp(selection){this->init();}
+
+ByChainColorOp::ByChainColorOp(const String& selection, int mask) : ColorOp(selection,mask){this->init();}
+
+void ByChainColorOp::init(){
+  color_grad_.SetColorAt(0,Color(1,1,0));
+  color_grad_.SetColorAt(0.16666,Color(1,0,0));
+  color_grad_.SetColorAt(0.33333,Color(0,1,1));
+  color_grad_.SetColorAt(0.5,Color(0,1,0));
+  color_grad_.SetColorAt(0.66666,Color(1,0,1));
+  color_grad_.SetColorAt(0.83333,Color(0,0,1));
+}
+
+bool ByChainColorOp::CanApplyTo(const GfxObjP& obj) const{
+  if(dynamic_cast<Entity*>(obj.get()))
+    return true;
+  return false;
+}
+
+void ByChainColorOp::ApplyTo(GfxObjP& objP) const{
+  GfxObj* obj = objP.get();
+  if(Entity* ent=dynamic_cast<Entity*>(obj)){
+    ent->Apply(*this, false);
+  }
+}
+
+gfx::Color ByChainColorOp::GetColor(String ident) const{
+  if(colors_.find(ident) == colors_.end())
+  {
+    colors_[ident] = GenerateColor(ident);
+  }
+  return colors_[ident];
+}
+
+gfx::ByChainColorOp ByChainColorOp::FromInfo(info::InfoGroup& group){
+  gfx::ColorOp op = ColorOp::FromInfo(group);
+  String selection = op.GetSelection();
+  int mask = op.GetMask();
+  return gfx::ByChainColorOp(selection, mask);
+}
+
+gfx::Color ByChainColorOp::GenerateColor(String& ident) const{
+  unsigned int size=colors_.size()-1;
+  int cnt = size % 6;
+  int factor = abs(size/6.0)+1;
+  float start = 1.0/(6.0*factor);
+  if(factor > 1 && !((factor+1) & 1)){
+    float old_start = 1.0 / (6.0 *abs(size/6.0));
+    start += old_start;
+  }
+  float value = start + (cnt / 6.0);
+  if(value >= 1){
+    value -=1;
+  }
+  return color_grad_.GetColorAt(value);
+}
+
+}}
+
diff --git a/modules/gfx/src/color_ops/by_chain_color_op.hh b/modules/gfx/src/color_ops/by_chain_color_op.hh
new file mode 100644
index 0000000000000000000000000000000000000000..6cd454a6e1b96eecf38aa900398d8b7867ba0959
--- /dev/null
+++ b/modules/gfx/src/color_ops/by_chain_color_op.hh
@@ -0,0 +1,61 @@
+//------------------------------------------------------------------------------
+// This file is part of the OpenStructure project <www.openstructure.org>
+//
+// Copyright (C) 2008-2010 by the OpenStructure authors
+//
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License as published by the Free
+// Software Foundation; either version 3.0 of the License, or (at your option)
+// any later version.
+// This library is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
+// details.
+//
+// You should have received a copy of the GNU Lesser General Public License
+// along with this library; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+//------------------------------------------------------------------------------
+#ifndef OST_COLOR_OPS_BY_CHAIN_COLOR_OP_HH
+#define OST_COLOR_OPS_BY_CHAIN_COLOR_OP_HH
+#include <map>
+
+#include <ost/info/info.hh>
+#include <ost/info/info_fw.hh>
+
+#include <ost/gfx/gradient.hh>
+#include <ost/gfx/color_ops/color_op.hh>
+
+/*
+  Author: Stefan Scheuber
+*/
+
+namespace ost { namespace gfx {
+
+class DLLEXPORT_OST_GFX ByChainColorOp: public ColorOp {
+public:
+  ByChainColorOp();
+  ByChainColorOp(const String& selection);
+  ByChainColorOp(const String& selection, int mask);
+
+  virtual bool CanApplyTo(const GfxObjP& obj) const;
+  virtual void ApplyTo(GfxObjP& obj) const;
+
+  virtual gfx::Color GetColor(String ident) const;
+
+  //virtual void ToInfo(info::InfoGroup& group) const;
+  static gfx::ByChainColorOp FromInfo(info::InfoGroup& group);
+
+private:
+  void init();
+  gfx::Color GenerateColor(String& ident) const;
+
+  mutable std::map<String,gfx::Color> colors_;
+
+  gfx::Gradient color_grad_;
+};
+
+}}
+
+#endif
+
diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc
index 8f06734f325c41b52ffcf38cd829ffa4e906d65f..54ddc5fadbeb9c2c8b02ac1b2f51a490c4058d74 100644
--- a/modules/gfx/src/entity.cc
+++ b/modules/gfx/src/entity.cc
@@ -710,6 +710,12 @@ void Entity::ColorByElement()
   this->Apply(cop);
 }
 
+void Entity::ColorByChain()
+{
+  ByChainColorOp cop = ByChainColorOp();
+  this->Apply(cop);
+}
+
 void Entity::ColorBy(const mol::EntityView& ev,
                      const String& prop,
                      const Gradient& g, float minv, float maxv)
@@ -878,6 +884,16 @@ void Entity::Apply(const gfx::ByElementColorOp& op, bool store)
   FlagRebuild();
 }
 
+void Entity::Apply(const gfx::ByChainColorOp& op, bool store)
+{
+  if(store){
+    ByChainColorOp* op_ptr = new ByChainColorOp(op);
+    this->AppendColorOp(op_ptr);
+  }
+  apply_color_op_to_renderer_list(renderer_.begin(), renderer_.end(), op);
+  FlagRebuild();
+}
+
 void Entity::Apply(const gfx::EntityViewColorOp& op, bool store)
 {
   if(store){
diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh
index 5c37201fbb56f8f929bc5588fcad0600a0976969..710f61ccf716b5a8e3408b0981e922614a673478 100644
--- a/modules/gfx/src/entity.hh
+++ b/modules/gfx/src/entity.hh
@@ -32,6 +32,7 @@
 #include <ost/gfx/render_options/render_options.hh>
 #include <ost/gfx/color_ops/color_op.hh>
 #include <ost/gfx/color_ops/by_element_color_op.hh>
+#include <ost/gfx/color_ops/by_chain_color_op.hh>
 #include <ost/gfx/color_ops/uniform_color_op.hh>
 #include <ost/gfx/color_ops/gradient_level_color_op.hh>
 #include <ost/gfx/color_ops/entity_view_color_op.hh>
@@ -156,6 +157,9 @@ public:
   /// \brief color by element
   void ColorByElement();
   
+  /// \brief color by chain
+  void ColorByChain();
+
   /// \brief get view
   mol::EntityView GetView() const;
 
@@ -222,6 +226,7 @@ public:
   void ResetRadiusBy();
 
   void Apply(const gfx::ByElementColorOp& op, bool store=true);
+  void Apply(const gfx::ByChainColorOp& op, bool store=true);
   void Apply(const gfx::UniformColorOp& op, bool store=true);
 
   void Apply(const gfx::GradientLevelColorOp& op, bool store=true);
diff --git a/modules/gfx/src/impl/connect_renderer_base.cc b/modules/gfx/src/impl/connect_renderer_base.cc
index 51a4afa3851322fc9849da6791a191aab4a8277d..3eccdac572f7b3afa0d2ebf6abdbfddb8808e5aa 100644
--- a/modules/gfx/src/impl/connect_renderer_base.cc
+++ b/modules/gfx/src/impl/connect_renderer_base.cc
@@ -207,6 +207,22 @@ void ConnectRendererBase::Apply(const gfx::ByElementColorOp& op)
   state_|=DIRTY_VA;
 }
 
+void ConnectRendererBase::Apply(const gfx::ByChainColorOp& op)
+{
+  if ((op.GetMask() & MAIN_COLOR)==0) {
+    return;
+  }
+  this->UpdateViews();
+  mol::Query q(op.GetSelection());
+  for (AtomEntryMap::iterator it=view_.atom_map.begin();
+       it!=view_.atom_map.end();++it) {
+    if (q.IsAtomSelected(it->second.atom)) {
+      it->second.color=op.GetColor(it->second.atom.GetResidue().GetChain().GetName());
+    }
+  }
+  state_|=DIRTY_VA;
+}
+
 void ConnectRendererBase::Apply(const gfx::UniformColorOp& op)
 {
   if ((op.GetMask() & MAIN_COLOR)==0) {
diff --git a/modules/gfx/src/impl/connect_renderer_base.hh b/modules/gfx/src/impl/connect_renderer_base.hh
index 06504f377374c9a8e6b2a04ba9655832e81255ea..78b730fc18c5bc56cf5b0edd3a7df89fda2d2d6e 100644
--- a/modules/gfx/src/impl/connect_renderer_base.hh
+++ b/modules/gfx/src/impl/connect_renderer_base.hh
@@ -40,6 +40,7 @@ public:
   virtual geom::AlignedCuboid GetBoundingBox() const;
   
   virtual void Apply(const gfx::ByElementColorOp& op);
+  virtual void Apply(const gfx::ByChainColorOp& op);
   virtual void Apply(const gfx::UniformColorOp& op);
   virtual void Apply(const gfx::GradientLevelColorOp& op);
   virtual void Apply(const gfx::EntityViewColorOp& op);
diff --git a/modules/gfx/src/impl/entity_renderer.hh b/modules/gfx/src/impl/entity_renderer.hh
index 2355e225f2716f2a137652a4fa58df24fa7c4c1f..b3f3b0cb129e36849de23cac5123df1d5020677f 100644
--- a/modules/gfx/src/impl/entity_renderer.hh
+++ b/modules/gfx/src/impl/entity_renderer.hh
@@ -35,6 +35,7 @@
 
 #include <ost/gfx/color_ops/color_op.hh>
 #include <ost/gfx/color_ops/by_element_color_op.hh>
+#include <ost/gfx/color_ops/by_chain_color_op.hh>
 #include <ost/gfx/color_ops/uniform_color_op.hh>
 #include <ost/gfx/color_ops/gradient_level_color_op.hh>
 #include <ost/gfx/color_ops/entity_view_color_op.hh>
@@ -138,6 +139,7 @@ public:
   virtual ~EntityRenderer(){}
 
   virtual void Apply(const gfx::ByElementColorOp& op)=0;
+  virtual void Apply(const gfx::ByChainColorOp& op)=0;
   virtual void Apply(const gfx::UniformColorOp& op)=0;
   virtual void Apply(const gfx::GradientLevelColorOp& op)=0;
   virtual void Apply(const gfx::EntityViewColorOp& op)=0;
diff --git a/modules/gfx/src/impl/trace_renderer_base.cc b/modules/gfx/src/impl/trace_renderer_base.cc
index ca2e991c11b5df22748812ab78d4a17af0a69da7..eab5351156850b2d2685bbf7b679f1cb9dafe564 100644
--- a/modules/gfx/src/impl/trace_renderer_base.cc
+++ b/modules/gfx/src/impl/trace_renderer_base.cc
@@ -94,6 +94,23 @@ void TraceRendererBase::Apply(const gfx::ByElementColorOp& op)
   state_|=DIRTY_VA;
 }
 
+void TraceRendererBase::Apply(const gfx::ByChainColorOp& op)
+{
+  this->UpdateViews();
+  mol::Query q(op.GetSelection());
+  for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) {
+    NodeListSubset& nl=trace_subset_[node_list];
+    for (int i=0; i<nl.GetSize();++i) {
+      if (q.IsAtomSelected(nl[i].atom)) {
+        Color clr =op.GetColor(nl[i].atom.GetResidue().GetChain().GetName());
+        this->set_node_entry_color(nl[i],op.GetMask(),clr);
+      }
+    }
+  }
+  state_|=DIRTY_VA;
+}
+
+
 void TraceRendererBase::Apply(const gfx::UniformColorOp& op)
 {
   this->UpdateViews();  
diff --git a/modules/gfx/src/impl/trace_renderer_base.hh b/modules/gfx/src/impl/trace_renderer_base.hh
index 68172d62fd38454c423673cdfae1e4791fac1a67..b102e1cc2c78c5ad1f2881e8530f51fb21a1b205 100644
--- a/modules/gfx/src/impl/trace_renderer_base.hh
+++ b/modules/gfx/src/impl/trace_renderer_base.hh
@@ -47,6 +47,7 @@ public:
   virtual bool HasDataToRender() const;
   virtual void UpdateViews();  
   virtual void Apply(const gfx::ByElementColorOp& op);
+  virtual void Apply(const gfx::ByChainColorOp& op);
   virtual void Apply(const gfx::UniformColorOp& op);
   virtual void Apply(const gfx::GradientLevelColorOp& op);
   virtual void Apply(const gfx::EntityViewColorOp& op);