diff --git a/enstools/feature/identification/_proto_gen/storm_pb2.py b/enstools/feature/identification/_proto_gen/storm_pb2.py
index f9b50d475432d230c4aec5fa3a62d00fbe261e09..e8a244db659c12a27203cc927dcad8c6b5bd28b4 100644
--- a/enstools/feature/identification/_proto_gen/storm_pb2.py
+++ b/enstools/feature/identification/_proto_gen/storm_pb2.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: tmpyjo4p1mf
+# source: tmpz751s9fm
 """Generated protocol buffer code."""
 from google.protobuf.internal import builder as _builder
 from google.protobuf import descriptor as _descriptor
@@ -13,10 +13,10 @@ _sym_db = _symbol_database.Default()
 
 
 
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btmpyjo4p1mf\"\x1f\n\x03Pos\x12\x0b\n\x03lat\x18\x01 \x02(\x02\x12\x0b\n\x03lon\x18\x02 \x02(\x02\"B\n\nProperties\x12\x14\n\x0cmin_pressure\x18\x01 \x02(\x02\x12\x1e\n\x10min_pressure_pos\x18\x02 \x02(\x0b\x32\x04.Pos\")\n\tVoxelData\x12\r\n\x05index\x18\x01 \x03(\r\x12\r\n\x05value\x18\x02 \x01(\x02\"-\n\nVertexData\x12\x10\n\x08position\x18\x01 \x03(\x02\x12\r\n\x05value\x18\x02 \x01(\x02\"+\n\x08\x46\x61\x63\x65\x44\x61ta\x12\x10\n\x08vertices\x18\x01 \x03(\r\x12\r\n\x05value\x18\x02 \x01(\x02\"C\n\x13VoxelRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12\x1e\n\nvoxel_data\x18\x02 \x03(\x0b\x32\n.VoxelData\"D\n\x12LineRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12 \n\x0bvertex_data\x18\x02 \x03(\x0b\x32\x0b.VertexData\"f\n\x16\x42oundaryRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12 \n\x0bvertex_data\x18\x02 \x03(\x0b\x32\x0b.VertexData\x12\x1c\n\tface_data\x18\x03 \x03(\x0b\x32\t.FaceData\"2\n\tGraphNode\x12\x0c\n\x04time\x18\x01 \x02(\t\x12\x17\n\x06object\x18\x02 \x02(\x0b\x32\x07.Object\"K\n\x0fGraphConnection\x12\x1a\n\x06parent\x18\x01 \x02(\x0b\x32\n.GraphNode\x12\x1c\n\x08\x63hildren\x18\x02 \x03(\x0b\x32\n.GraphNode\".\n\x0bObjectGraph\x12\x1f\n\x05\x65\x64ges\x18\x01 \x03(\x0b\x32\x10.GraphConnection\"\xb4\x01\n\x06Object\x12\n\n\x02id\x18\x01 \x02(\x05\x12%\n\x08line_rep\x18\x02 \x03(\x0b\x32\x13.LineRepresentation\x12\'\n\tvoxel_rep\x18\x03 \x01(\x0b\x32\x14.VoxelRepresentation\x12-\n\x0c\x62oundary_rep\x18\x04 \x03(\x0b\x32\x17.BoundaryRepresentation\x12\x1f\n\nproperties\x18\x05 \x01(\x0b\x32\x0b.Properties\"8\n\x08Timestep\x12\x12\n\nvalid_time\x18\x01 \x01(\t\x12\x18\n\x07objects\x18\x02 \x03(\x0b\x32\x07.Object\"\x99\x01\n\x0cTrackableSet\x12\x11\n\tinit_time\x18\x01 \x01(\t\x12\x0e\n\x06member\x18\x02 \x01(\r\x12\r\n\x05level\x18\x03 \x01(\x02\x12\x1c\n\ttimesteps\x18\x04 \x03(\x0b\x32\t.Timestep\x12\x1b\n\x05graph\x18\x05 \x01(\x0b\x32\x0c.ObjectGraph\x12\x1c\n\x06tracks\x18\x06 \x03(\x0b\x32\x0c.ObjectGraph\"_\n\x12\x44\x61tasetDescription\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x66ile\x18\x02 \x01(\t\x12\x10\n\x08run_time\x18\x03 \x02(\t\x12\x1b\n\x04sets\x18\x04 \x03(\x0b\x32\r.TrackableSet')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btmpz751s9fm\"\x1f\n\x03Pos\x12\x0b\n\x03lat\x18\x01 \x02(\x02\x12\x0b\n\x03lon\x18\x02 \x02(\x02\"B\n\nProperties\x12\x14\n\x0cmin_pressure\x18\x01 \x02(\x02\x12\x1e\n\x10min_pressure_pos\x18\x02 \x02(\x0b\x32\x04.Pos\")\n\tVoxelData\x12\r\n\x05index\x18\x01 \x03(\r\x12\r\n\x05value\x18\x02 \x01(\x02\"-\n\nVertexData\x12\x10\n\x08position\x18\x01 \x03(\x02\x12\r\n\x05value\x18\x02 \x01(\x02\"+\n\x08\x46\x61\x63\x65\x44\x61ta\x12\x10\n\x08vertices\x18\x01 \x03(\r\x12\r\n\x05value\x18\x02 \x01(\x02\"C\n\x13VoxelRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12\x1e\n\nvoxel_data\x18\x02 \x03(\x0b\x32\n.VoxelData\"D\n\x12LineRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12 \n\x0bvertex_data\x18\x02 \x03(\x0b\x32\x0b.VertexData\"f\n\x16\x42oundaryRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12 \n\x0bvertex_data\x18\x02 \x03(\x0b\x32\x0b.VertexData\x12\x1c\n\tface_data\x18\x03 \x03(\x0b\x32\t.FaceData\"2\n\tGraphNode\x12\x0c\n\x04time\x18\x01 \x02(\t\x12\x17\n\x06object\x18\x02 \x02(\x0b\x32\x07.Object\"K\n\x0fGraphConnection\x12\x1a\n\x06parent\x18\x01 \x02(\x0b\x32\n.GraphNode\x12\x1c\n\x08\x63hildren\x18\x02 \x03(\x0b\x32\n.GraphNode\".\n\x0bObjectGraph\x12\x1f\n\x05\x65\x64ges\x18\x01 \x03(\x0b\x32\x10.GraphConnection\"\xb4\x01\n\x06Object\x12\n\n\x02id\x18\x01 \x02(\x05\x12%\n\x08line_rep\x18\x02 \x03(\x0b\x32\x13.LineRepresentation\x12\'\n\tvoxel_rep\x18\x03 \x01(\x0b\x32\x14.VoxelRepresentation\x12-\n\x0c\x62oundary_rep\x18\x04 \x03(\x0b\x32\x17.BoundaryRepresentation\x12\x1f\n\nproperties\x18\x05 \x01(\x0b\x32\x0b.Properties\"8\n\x08Timestep\x12\x12\n\nvalid_time\x18\x01 \x01(\t\x12\x18\n\x07objects\x18\x02 \x03(\x0b\x32\x07.Object\"\x99\x01\n\x0cTrackableSet\x12\x11\n\tinit_time\x18\x01 \x01(\t\x12\x0e\n\x06member\x18\x02 \x01(\r\x12\r\n\x05level\x18\x03 \x01(\x02\x12\x1c\n\ttimesteps\x18\x04 \x03(\x0b\x32\t.Timestep\x12\x1b\n\x05graph\x18\x05 \x01(\x0b\x32\x0c.ObjectGraph\x12\x1c\n\x06tracks\x18\x06 \x03(\x0b\x32\x0c.ObjectGraph\"_\n\x12\x44\x61tasetDescription\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x66ile\x18\x02 \x01(\t\x12\x10\n\x08run_time\x18\x03 \x02(\t\x12\x1b\n\x04sets\x18\x04 \x03(\x0b\x32\r.TrackableSet')
 
 _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
-_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tmpyjo4p1mf_pb2', globals())
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tmpz751s9fm_pb2', globals())
 if _descriptor._USE_C_DESCRIPTORS == False:
 
   DESCRIPTOR._options = None
diff --git a/enstools/feature/identification/_proto_gen/threshold_pb2.py b/enstools/feature/identification/_proto_gen/threshold_pb2.py
index 3e4a7b480c8eb20b2b8b56eb1e4cfd6d3239dbd9..a3639bc8f713c39776a44aafe3805f67bd0b79ca 100644
--- a/enstools/feature/identification/_proto_gen/threshold_pb2.py
+++ b/enstools/feature/identification/_proto_gen/threshold_pb2.py
@@ -1,6 +1,10 @@
 # -*- coding: utf-8 -*-
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
+<<<<<<< HEAD
 # source: tmpwdhwhb1j
+=======
+# source: tmpncjfrx7c
+>>>>>>> origin/aew_kitweather
 """Generated protocol buffer code."""
 from google.protobuf.internal import builder as _builder
 from google.protobuf import descriptor as _descriptor
@@ -13,7 +17,829 @@ _sym_db = _symbol_database.Default()
 
 
 
+<<<<<<< HEAD
 DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0btmpwdhwhb1j\"6\n\tMaskArray\x12\r\n\x05shape\x18\x01 \x03(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x02(\x0c\x12\x0c\n\x04zlib\x18\x03 \x02(\x08\"u\n\nProperties\x12\x18\n\x04mask\x18\x01 \x02(\x0b\x32\n.MaskArray\x12\x17\n\x0fouter_threshold\x18\x02 \x02(\x02\x12\x17\n\x0finner_threshold\x18\x03 \x02(\x02\x12\x1b\n\x13\x63omparison_operator\x18\x04 \x02(\t\")\n\tVoxelData\x12\r\n\x05index\x18\x01 \x03(\r\x12\r\n\x05value\x18\x02 \x01(\x02\"-\n\nVertexData\x12\x10\n\x08position\x18\x01 \x03(\x02\x12\r\n\x05value\x18\x02 \x01(\x02\"+\n\x08\x46\x61\x63\x65\x44\x61ta\x12\x10\n\x08vertices\x18\x01 \x03(\r\x12\r\n\x05value\x18\x02 \x01(\x02\"C\n\x13VoxelRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12\x1e\n\nvoxel_data\x18\x02 \x03(\x0b\x32\n.VoxelData\"D\n\x12LineRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12 \n\x0bvertex_data\x18\x02 \x03(\x0b\x32\x0b.VertexData\"f\n\x16\x42oundaryRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12 \n\x0bvertex_data\x18\x02 \x03(\x0b\x32\x0b.VertexData\x12\x1c\n\tface_data\x18\x03 \x03(\x0b\x32\t.FaceData\"2\n\tGraphNode\x12\x0c\n\x04time\x18\x01 \x02(\t\x12\x17\n\x06object\x18\x02 \x02(\x0b\x32\x07.Object\"K\n\x0fGraphConnection\x12\x1a\n\x06parent\x18\x01 \x02(\x0b\x32\n.GraphNode\x12\x1c\n\x08\x63hildren\x18\x02 \x03(\x0b\x32\n.GraphNode\".\n\x0bObjectGraph\x12\x1f\n\x05\x65\x64ges\x18\x01 \x03(\x0b\x32\x10.GraphConnection\"\xb4\x01\n\x06Object\x12\n\n\x02id\x18\x01 \x02(\x05\x12%\n\x08line_rep\x18\x02 \x03(\x0b\x32\x13.LineRepresentation\x12\'\n\tvoxel_rep\x18\x03 \x01(\x0b\x32\x14.VoxelRepresentation\x12-\n\x0c\x62oundary_rep\x18\x04 \x03(\x0b\x32\x17.BoundaryRepresentation\x12\x1f\n\nproperties\x18\x05 \x01(\x0b\x32\x0b.Properties\"8\n\x08Timestep\x12\x12\n\nvalid_time\x18\x01 \x01(\t\x12\x18\n\x07objects\x18\x02 \x03(\x0b\x32\x07.Object\"\x99\x01\n\x0cTrackableSet\x12\x11\n\tinit_time\x18\x01 \x01(\t\x12\x0e\n\x06member\x18\x02 \x01(\r\x12\r\n\x05level\x18\x03 \x01(\x02\x12\x1c\n\ttimesteps\x18\x04 \x03(\x0b\x32\t.Timestep\x12\x1b\n\x05graph\x18\x05 \x01(\x0b\x32\x0c.ObjectGraph\x12\x1c\n\x06tracks\x18\x06 \x03(\x0b\x32\x0c.ObjectGraph\"_\n\x12\x44\x61tasetDescription\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x66ile\x18\x02 \x01(\t\x12\x10\n\x08run_time\x18\x03 \x02(\t\x12\x1b\n\x04sets\x18\x04 \x03(\x0b\x32\r.TrackableSet')
+=======
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='tmpncjfrx7c',
+  package='',
+  syntax='proto2',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x0btmpncjfrx7c\"6\n\tMaskArray\x12\r\n\x05shape\x18\x01 \x03(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x02(\x0c\x12\x0c\n\x04zlib\x18\x03 \x02(\x08\"u\n\nProperties\x12\x18\n\x04mask\x18\x01 \x02(\x0b\x32\n.MaskArray\x12\x17\n\x0fouter_threshold\x18\x02 \x02(\x02\x12\x17\n\x0finner_threshold\x18\x03 \x02(\x02\x12\x1b\n\x13\x63omparison_operator\x18\x04 \x02(\t\")\n\tVoxelData\x12\r\n\x05index\x18\x01 \x03(\r\x12\r\n\x05value\x18\x02 \x01(\x02\"-\n\nVertexData\x12\x10\n\x08position\x18\x01 \x03(\x02\x12\r\n\x05value\x18\x02 \x01(\x02\"+\n\x08\x46\x61\x63\x65\x44\x61ta\x12\x10\n\x08vertices\x18\x01 \x03(\r\x12\r\n\x05value\x18\x02 \x01(\x02\"C\n\x13VoxelRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12\x1e\n\nvoxel_data\x18\x02 \x03(\x0b\x32\n.VoxelData\"D\n\x12LineRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12 \n\x0bvertex_data\x18\x02 \x03(\x0b\x32\x0b.VertexData\"f\n\x16\x42oundaryRepresentation\x12\x0c\n\x04\x64\x65sc\x18\x01 \x01(\t\x12 \n\x0bvertex_data\x18\x02 \x03(\x0b\x32\x0b.VertexData\x12\x1c\n\tface_data\x18\x03 \x03(\x0b\x32\t.FaceData\"2\n\tGraphNode\x12\x0c\n\x04time\x18\x01 \x02(\t\x12\x17\n\x06object\x18\x02 \x02(\x0b\x32\x07.Object\"I\n\x0fGraphConnection\x12\x1a\n\x06parent\x18\x01 \x02(\x0b\x32\n.GraphNode\x12\x1a\n\x06\x63hilds\x18\x02 \x03(\x0b\x32\n.GraphNode\".\n\x0bObjectGraph\x12\x1f\n\x05\x65\x64ges\x18\x01 \x03(\x0b\x32\x10.GraphConnection\"\xb4\x01\n\x06Object\x12\n\n\x02id\x18\x01 \x02(\x05\x12%\n\x08line_rep\x18\x02 \x03(\x0b\x32\x13.LineRepresentation\x12\'\n\tvoxel_rep\x18\x03 \x01(\x0b\x32\x14.VoxelRepresentation\x12-\n\x0c\x62oundary_rep\x18\x04 \x03(\x0b\x32\x17.BoundaryRepresentation\x12\x1f\n\nproperties\x18\x05 \x01(\x0b\x32\x0b.Properties\"8\n\x08Timestep\x12\x12\n\nvalid_time\x18\x01 \x01(\t\x12\x18\n\x07objects\x18\x02 \x03(\x0b\x32\x07.Object\"\x99\x01\n\x0cTrackableSet\x12\x11\n\tinit_time\x18\x01 \x01(\t\x12\x0e\n\x06member\x18\x02 \x01(\r\x12\r\n\x05level\x18\x03 \x01(\x02\x12\x1c\n\ttimesteps\x18\x04 \x03(\x0b\x32\t.Timestep\x12\x1b\n\x05graph\x18\x05 \x01(\x0b\x32\x0c.ObjectGraph\x12\x1c\n\x06tracks\x18\x06 \x03(\x0b\x32\x0c.ObjectGraph\"_\n\x12\x44\x61tasetDescription\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x66ile\x18\x02 \x01(\t\x12\x10\n\x08run_time\x18\x03 \x02(\t\x12\x1b\n\x04sets\x18\x04 \x03(\x0b\x32\r.TrackableSet'
+)
+
+
+
+
+_MASKARRAY = _descriptor.Descriptor(
+  name='MaskArray',
+  full_name='MaskArray',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='shape', full_name='MaskArray.shape', index=0,
+      number=1, type=5, cpp_type=1, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='MaskArray.data', index=1,
+      number=2, type=12, cpp_type=9, label=2,
+      has_default_value=False, default_value=b"",
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='zlib', full_name='MaskArray.zlib', index=2,
+      number=3, type=8, cpp_type=7, label=2,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=15,
+  serialized_end=69,
+)
+
+
+_PROPERTIES = _descriptor.Descriptor(
+  name='Properties',
+  full_name='Properties',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='mask', full_name='Properties.mask', index=0,
+      number=1, type=11, cpp_type=10, label=2,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='outer_threshold', full_name='Properties.outer_threshold', index=1,
+      number=2, type=2, cpp_type=6, label=2,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='inner_threshold', full_name='Properties.inner_threshold', index=2,
+      number=3, type=2, cpp_type=6, label=2,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='comparison_operator', full_name='Properties.comparison_operator', index=3,
+      number=4, type=9, cpp_type=9, label=2,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=71,
+  serialized_end=188,
+)
+
+
+_VOXELDATA = _descriptor.Descriptor(
+  name='VoxelData',
+  full_name='VoxelData',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='index', full_name='VoxelData.index', index=0,
+      number=1, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='VoxelData.value', index=1,
+      number=2, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=190,
+  serialized_end=231,
+)
+
+
+_VERTEXDATA = _descriptor.Descriptor(
+  name='VertexData',
+  full_name='VertexData',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='position', full_name='VertexData.position', index=0,
+      number=1, type=2, cpp_type=6, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='VertexData.value', index=1,
+      number=2, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=233,
+  serialized_end=278,
+)
+
+
+_FACEDATA = _descriptor.Descriptor(
+  name='FaceData',
+  full_name='FaceData',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='vertices', full_name='FaceData.vertices', index=0,
+      number=1, type=13, cpp_type=3, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='FaceData.value', index=1,
+      number=2, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=280,
+  serialized_end=323,
+)
+
+
+_VOXELREPRESENTATION = _descriptor.Descriptor(
+  name='VoxelRepresentation',
+  full_name='VoxelRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='desc', full_name='VoxelRepresentation.desc', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='voxel_data', full_name='VoxelRepresentation.voxel_data', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=325,
+  serialized_end=392,
+)
+
+
+_LINEREPRESENTATION = _descriptor.Descriptor(
+  name='LineRepresentation',
+  full_name='LineRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='desc', full_name='LineRepresentation.desc', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='vertex_data', full_name='LineRepresentation.vertex_data', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=394,
+  serialized_end=462,
+)
+
+
+_BOUNDARYREPRESENTATION = _descriptor.Descriptor(
+  name='BoundaryRepresentation',
+  full_name='BoundaryRepresentation',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='desc', full_name='BoundaryRepresentation.desc', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='vertex_data', full_name='BoundaryRepresentation.vertex_data', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='face_data', full_name='BoundaryRepresentation.face_data', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=464,
+  serialized_end=566,
+)
+
+
+_GRAPHNODE = _descriptor.Descriptor(
+  name='GraphNode',
+  full_name='GraphNode',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='time', full_name='GraphNode.time', index=0,
+      number=1, type=9, cpp_type=9, label=2,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='object', full_name='GraphNode.object', index=1,
+      number=2, type=11, cpp_type=10, label=2,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=568,
+  serialized_end=618,
+)
+
+
+_GRAPHCONNECTION = _descriptor.Descriptor(
+  name='GraphConnection',
+  full_name='GraphConnection',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='parent', full_name='GraphConnection.parent', index=0,
+      number=1, type=11, cpp_type=10, label=2,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='childs', full_name='GraphConnection.childs', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=620,
+  serialized_end=693,
+)
+
+
+_OBJECTGRAPH = _descriptor.Descriptor(
+  name='ObjectGraph',
+  full_name='ObjectGraph',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='edges', full_name='ObjectGraph.edges', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=695,
+  serialized_end=741,
+)
+
+
+_OBJECT = _descriptor.Descriptor(
+  name='Object',
+  full_name='Object',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='id', full_name='Object.id', index=0,
+      number=1, type=5, cpp_type=1, label=2,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='line_rep', full_name='Object.line_rep', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='voxel_rep', full_name='Object.voxel_rep', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='boundary_rep', full_name='Object.boundary_rep', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='properties', full_name='Object.properties', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=744,
+  serialized_end=924,
+)
+
+
+_TIMESTEP = _descriptor.Descriptor(
+  name='Timestep',
+  full_name='Timestep',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='valid_time', full_name='Timestep.valid_time', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='objects', full_name='Timestep.objects', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=926,
+  serialized_end=982,
+)
+
+
+_TRACKABLESET = _descriptor.Descriptor(
+  name='TrackableSet',
+  full_name='TrackableSet',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='init_time', full_name='TrackableSet.init_time', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='member', full_name='TrackableSet.member', index=1,
+      number=2, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='level', full_name='TrackableSet.level', index=2,
+      number=3, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='timesteps', full_name='TrackableSet.timesteps', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='graph', full_name='TrackableSet.graph', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='tracks', full_name='TrackableSet.tracks', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=985,
+  serialized_end=1138,
+)
+
+
+_DATASETDESCRIPTION = _descriptor.Descriptor(
+  name='DatasetDescription',
+  full_name='DatasetDescription',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='DatasetDescription.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='file', full_name='DatasetDescription.file', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='run_time', full_name='DatasetDescription.run_time', index=2,
+      number=3, type=9, cpp_type=9, label=2,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='sets', full_name='DatasetDescription.sets', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto2',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1140,
+  serialized_end=1235,
+)
+
+_PROPERTIES.fields_by_name['mask'].message_type = _MASKARRAY
+_VOXELREPRESENTATION.fields_by_name['voxel_data'].message_type = _VOXELDATA
+_LINEREPRESENTATION.fields_by_name['vertex_data'].message_type = _VERTEXDATA
+_BOUNDARYREPRESENTATION.fields_by_name['vertex_data'].message_type = _VERTEXDATA
+_BOUNDARYREPRESENTATION.fields_by_name['face_data'].message_type = _FACEDATA
+_GRAPHNODE.fields_by_name['object'].message_type = _OBJECT
+_GRAPHCONNECTION.fields_by_name['parent'].message_type = _GRAPHNODE
+_GRAPHCONNECTION.fields_by_name['childs'].message_type = _GRAPHNODE
+_OBJECTGRAPH.fields_by_name['edges'].message_type = _GRAPHCONNECTION
+_OBJECT.fields_by_name['line_rep'].message_type = _LINEREPRESENTATION
+_OBJECT.fields_by_name['voxel_rep'].message_type = _VOXELREPRESENTATION
+_OBJECT.fields_by_name['boundary_rep'].message_type = _BOUNDARYREPRESENTATION
+_OBJECT.fields_by_name['properties'].message_type = _PROPERTIES
+_TIMESTEP.fields_by_name['objects'].message_type = _OBJECT
+_TRACKABLESET.fields_by_name['timesteps'].message_type = _TIMESTEP
+_TRACKABLESET.fields_by_name['graph'].message_type = _OBJECTGRAPH
+_TRACKABLESET.fields_by_name['tracks'].message_type = _OBJECTGRAPH
+_DATASETDESCRIPTION.fields_by_name['sets'].message_type = _TRACKABLESET
+DESCRIPTOR.message_types_by_name['MaskArray'] = _MASKARRAY
+DESCRIPTOR.message_types_by_name['Properties'] = _PROPERTIES
+DESCRIPTOR.message_types_by_name['VoxelData'] = _VOXELDATA
+DESCRIPTOR.message_types_by_name['VertexData'] = _VERTEXDATA
+DESCRIPTOR.message_types_by_name['FaceData'] = _FACEDATA
+DESCRIPTOR.message_types_by_name['VoxelRepresentation'] = _VOXELREPRESENTATION
+DESCRIPTOR.message_types_by_name['LineRepresentation'] = _LINEREPRESENTATION
+DESCRIPTOR.message_types_by_name['BoundaryRepresentation'] = _BOUNDARYREPRESENTATION
+DESCRIPTOR.message_types_by_name['GraphNode'] = _GRAPHNODE
+DESCRIPTOR.message_types_by_name['GraphConnection'] = _GRAPHCONNECTION
+DESCRIPTOR.message_types_by_name['ObjectGraph'] = _OBJECTGRAPH
+DESCRIPTOR.message_types_by_name['Object'] = _OBJECT
+DESCRIPTOR.message_types_by_name['Timestep'] = _TIMESTEP
+DESCRIPTOR.message_types_by_name['TrackableSet'] = _TRACKABLESET
+DESCRIPTOR.message_types_by_name['DatasetDescription'] = _DATASETDESCRIPTION
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+MaskArray = _reflection.GeneratedProtocolMessageType('MaskArray', (_message.Message,), {
+  'DESCRIPTOR' : _MASKARRAY,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:MaskArray)
+  })
+_sym_db.RegisterMessage(MaskArray)
+
+Properties = _reflection.GeneratedProtocolMessageType('Properties', (_message.Message,), {
+  'DESCRIPTOR' : _PROPERTIES,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:Properties)
+  })
+_sym_db.RegisterMessage(Properties)
+
+VoxelData = _reflection.GeneratedProtocolMessageType('VoxelData', (_message.Message,), {
+  'DESCRIPTOR' : _VOXELDATA,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:VoxelData)
+  })
+_sym_db.RegisterMessage(VoxelData)
+
+VertexData = _reflection.GeneratedProtocolMessageType('VertexData', (_message.Message,), {
+  'DESCRIPTOR' : _VERTEXDATA,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:VertexData)
+  })
+_sym_db.RegisterMessage(VertexData)
+
+FaceData = _reflection.GeneratedProtocolMessageType('FaceData', (_message.Message,), {
+  'DESCRIPTOR' : _FACEDATA,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:FaceData)
+  })
+_sym_db.RegisterMessage(FaceData)
+
+VoxelRepresentation = _reflection.GeneratedProtocolMessageType('VoxelRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _VOXELREPRESENTATION,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:VoxelRepresentation)
+  })
+_sym_db.RegisterMessage(VoxelRepresentation)
+
+LineRepresentation = _reflection.GeneratedProtocolMessageType('LineRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _LINEREPRESENTATION,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:LineRepresentation)
+  })
+_sym_db.RegisterMessage(LineRepresentation)
+
+BoundaryRepresentation = _reflection.GeneratedProtocolMessageType('BoundaryRepresentation', (_message.Message,), {
+  'DESCRIPTOR' : _BOUNDARYREPRESENTATION,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:BoundaryRepresentation)
+  })
+_sym_db.RegisterMessage(BoundaryRepresentation)
+
+GraphNode = _reflection.GeneratedProtocolMessageType('GraphNode', (_message.Message,), {
+  'DESCRIPTOR' : _GRAPHNODE,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:GraphNode)
+  })
+_sym_db.RegisterMessage(GraphNode)
+
+GraphConnection = _reflection.GeneratedProtocolMessageType('GraphConnection', (_message.Message,), {
+  'DESCRIPTOR' : _GRAPHCONNECTION,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:GraphConnection)
+  })
+_sym_db.RegisterMessage(GraphConnection)
+
+ObjectGraph = _reflection.GeneratedProtocolMessageType('ObjectGraph', (_message.Message,), {
+  'DESCRIPTOR' : _OBJECTGRAPH,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:ObjectGraph)
+  })
+_sym_db.RegisterMessage(ObjectGraph)
+
+Object = _reflection.GeneratedProtocolMessageType('Object', (_message.Message,), {
+  'DESCRIPTOR' : _OBJECT,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:Object)
+  })
+_sym_db.RegisterMessage(Object)
+
+Timestep = _reflection.GeneratedProtocolMessageType('Timestep', (_message.Message,), {
+  'DESCRIPTOR' : _TIMESTEP,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:Timestep)
+  })
+_sym_db.RegisterMessage(Timestep)
+
+TrackableSet = _reflection.GeneratedProtocolMessageType('TrackableSet', (_message.Message,), {
+  'DESCRIPTOR' : _TRACKABLESET,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:TrackableSet)
+  })
+_sym_db.RegisterMessage(TrackableSet)
+
+DatasetDescription = _reflection.GeneratedProtocolMessageType('DatasetDescription', (_message.Message,), {
+  'DESCRIPTOR' : _DATASETDESCRIPTION,
+  '__module__' : 'tmpncjfrx7c_pb2'
+  # @@protoc_insertion_point(class_scope:DatasetDescription)
+  })
+_sym_db.RegisterMessage(DatasetDescription)
+>>>>>>> origin/aew_kitweather
 
 _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
 _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tmpwdhwhb1j_pb2', globals())
diff --git a/enstools/feature/identification/african_easterly_waves/colorpalette_dyamond_prec_rate.txt b/enstools/feature/identification/african_easterly_waves/colorpalette_dyamond_prec_rate.txt
new file mode 100644
index 0000000000000000000000000000000000000000..559a70cb69b616768853760d6127ebbdd68558ab
--- /dev/null
+++ b/enstools/feature/identification/african_easterly_waves/colorpalette_dyamond_prec_rate.txt
@@ -0,0 +1,11 @@
+163,205,231
+120,149,223
+ 81, 92,216
+ 63,164, 52
+ 86,209, 76
+255,245, 75
+254,185, 63
+251,136, 49
+251, 22, 33
+184, 18, 26
+135,  7, 18
diff --git a/enstools/feature/identification/african_easterly_waves/configuration.py b/enstools/feature/identification/african_easterly_waves/configuration.py
index e35f0f19dce8a63e5bd977ac45b39ec124803f4d..566232440302738143cad5163a477fc24b7106d3 100644
--- a/enstools/feature/identification/african_easterly_waves/configuration.py
+++ b/enstools/feature/identification/african_easterly_waves/configuration.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 from os.path import expanduser, join
 from datetime import timedelta
+import numpy as np
 
 # data area
 # latN = 35
@@ -11,12 +12,32 @@ data_lat = (-35, 35)
 data_lon = (-100, 45)
 
 aew_clim_dir = '/home/ws/he7273/phd_all/data/aew/clim/cv_clim_era5.nc' # 'C:\\Users\\Christoph\\phd\\data\\enstools-feature\\cv_clim_era5.nc' # '/home/christoph/phd/data/aew/clim/cv_clim_era5.nc' # '/home/christoph/phd/data/framework_example_ds/aew/' # '/project/meteo/w2w/C3/fischer/belanger/aew_clim/' #
-in_files = '/home/ws/he7273/phd_all/data/coll_oper/three/all.nc' # 'C:\\Users\\Christoph\\phd\\data\\enstools-feature\\2008_sum_uv.nc' # '/home/christoph/phd/data/framework_example_ds/aew/cv_aug_08.nc'
+in_files = '/home/ws/he7273/phd_all/data/coll_oper/jja2021/jja2021.nc' # 'C:\\Users\\Christoph\\phd\\data\\enstools-feature\\2008_sum_uv.nc' # '/home/christoph/phd/data/framework_example_ds/aew/cv_aug_08.nc'
 
 out_dir = join('/home/ws/he7273/phd_all/data/aew/out/') # '/project/meteo/w2w/C3/fischer/belanger/out/'
 plot_dir = join('/home/ws/he7273/phd_all/data/aew/plots/') # '/project/meteo/w2w/C3/fischer/belanger/plots/'
 
-cv_data_dir = '/project/meteo/w2w/C2/athul/data_athul/AEW_cv_data/' # reference where ALL cv data is (for clim calc.)
+timedelta_ana = np.timedelta64(7, 'D')
+
+# aew_kitweather_ecmwf_dir = '/lsdf/MOD/Gruppe_Transregio/Gruppe_Knippertz/kitweather/data/ecmwf-hres/forecasts/'
+# num_files_ecmwf = 41 # files in finished forecast data
+# file_prefix_ecmwf = 'ecmwf-hres_latlon_1.0deg_'
+# file_prefix_ecmwf_rain = 'ecmwf-hres_latlon_0.4deg_'
+plot_dir_ecmwf = '/home/iconeps/plots/aew/ecmwf-hres/' # '/project/meteo/w2w/C3/fischer/belanger/plots/'
+
+# aew_kitweather_icon_dir = '/lsdf/MOD/Gruppe_Transregio/Gruppe_Knippertz/kitweather/data/icon-global-det/forecasts/'
+# num_files_icon = 31 # files in finished forecast data
+# file_prefix_icon = 'icon-global-det_latlon_1.0deg_'
+# file_prefix_icon_rain = 'icon-global-det_latlon_0.25deg_'
+plot_dir_icon = '/home/iconeps/plots/aew/icon-global-det/' # '/project/meteo/w2w/C3/fischer/belanger/plots/'
+plot_dir_gfs = '/home/iconeps/plots/aew/gfs/'
+
+latest_run_dir = '/home/iconeps/plots/aew/'
+latest_run_info_file_name = 'latest_aew_run.txt'
+
+# out_dir = join(expanduser("~") + '/phd/data/aew/out/') # '/project/meteo/w2w/C3/fischer/belanger/out/'
+
+cv_data_dir = '/project/meteo/w2w/C2/athul/data_athul/AEW_cv_data/' # reference where ALL cv data is (only for clim calc.)
 cv_data_ex = join(cv_data_dir, '*.nc')
 
 
@@ -35,11 +56,12 @@ wave_filter_lat = (0, 30)
 wave_filter_lon = (-110, 55)
 
 levels = [700]  # 700 hPa
-u_dim = 'u700_fc'
-v_dim = 'v700_fc'
+u_dim = 'u700_rea'
+v_dim = 'v700_rea'
 
 # time of interest, if None all
 # june-oct is AEW season
+
 start_date = None # '2008-08-01T00:00' #  # '2008-08-01T00:00'
 end_date = None # '2008-08-15T00:00' # None # '2008-08-03T00:00'
 
diff --git a/enstools/feature/identification/african_easterly_waves/identification.py b/enstools/feature/identification/african_easterly_waves/identification.py
index 4ae87cb858bf9a7fec0c8bc311963cc4e749ef4d..e4e157ef505c9f447e97fcdcd25c27d85da5eeb3 100644
--- a/enstools/feature/identification/african_easterly_waves/identification.py
+++ b/enstools/feature/identification/african_easterly_waves/identification.py
@@ -7,6 +7,7 @@ import metpy.calc as mpcalc
 from .util import calc_adv
 from matplotlib import pyplot as plt
 import cartopy.crs as ccrs
+
 from .processing import populate_object, compute_cv
 from skimage.draw import line_aa
 from enstools.feature.util.enstools_utils import get_u_var, get_v_var, get_vertical_dim, get_longitude_dim, get_latitude_dim
@@ -82,8 +83,13 @@ class AEWIdentification(IdentificationStrategy):
         # --------------- SUBSET DATA ACCORDING TO CFG
         start_date_dt = np.datetime64(self.config.start_date) if self.config.start_date is not None else None
         end_date_dt = np.datetime64(self.config.end_date) if self.config.end_date is not None else None
-        # get the data we want to investigate
+        
+        # if data is lon=0..360, change it to -180..180
+        dataset.coords[lon_str] = (dataset.coords[lon_str] + 180) % 360 - 180
+        dataset = dataset.sortby(dataset[lon_str])
 
+        # get the data we want to investigate
+        dataset = dataset.sortby(lat_str) # in case of descending
         dataset = dataset.sel(
             **{lat_str: slice(lat_range[0], lat_range[1])},
             **{lon_str: slice(lon_range[0], lon_range[1])},
@@ -123,7 +129,7 @@ class AEWIdentification(IdentificationStrategy):
             print("Curvature Vorticity not found, trying to compute it out of U and V...")
             dataset = compute_cv(dataset, u_name, v_name, self.config.cv_name)
 
-            # make dataset to 2.5 (or same as cv_clim)
+        # make dataset to 2.5 (or same as cv_clim)
         dataset = dataset.interp({lat_str: cv_clim.coords[lat_str], lon_str: cv_clim.coords[lon_str]})
 
         # make sure that lat and lon are last two dimensions
@@ -139,8 +145,10 @@ class AEWIdentification(IdentificationStrategy):
         v = dataset[v_name]
         cv = dataset[self.config.cv_name]
         # smooth CV with kernel
+
         cv = mpcalc.smooth_n_point(cv, n=9, passes=2).metpy.dequantify()
 
+
         # create hourofyear to get anomalies
         cv = cv.assign_coords(hourofyear=cv.time.dt.strftime("%m-%d %H"))
         cv_anom = cv.groupby('hourofyear') - cv_clim.cv
@@ -156,7 +164,7 @@ class AEWIdentification(IdentificationStrategy):
         perc_mask = perc_mask_h.swap_dims(dims_dict={'hourofyear': 'time'})
 
         cv_perc_thresh = np.nanpercentile(cv, self.config.cv_percentile)  # 66th percentile of cv anomalies
-        print(cv_perc_thresh)
+        # print(cv_perc_thresh)
 
         print('Locating wave troughs...')
         # filter the advection field given our conditions:
@@ -194,6 +202,8 @@ class AEWIdentification(IdentificationStrategy):
         dataset['lat05'].attrs['units'] = 'degrees_north'
         dataset['lon05'].attrs['units'] = 'degrees_east'
 
+        dataset = dataset.drop_dims('step') # TODO REMOVE
+
         return dataset
 
     def identify(self, data_chunk: xr.Dataset, **kwargs):
diff --git a/enstools/feature/identification/african_easterly_waves/plotting.py b/enstools/feature/identification/african_easterly_waves/plotting.py
index 9b5ed179972e6dbf07ae5692dc8b6858a85c3bf0..d95c4f3461735ba0dc1961353a16252f510d2f9b 100644
--- a/enstools/feature/identification/african_easterly_waves/plotting.py
+++ b/enstools/feature/identification/african_easterly_waves/plotting.py
@@ -2,7 +2,9 @@ import os.path
 
 from matplotlib import pyplot as plt
 import numpy as np
+from PIL import Image
 import matplotlib
+import matplotlib as mpl
 import matplotlib.patches as patches
 import cartopy.crs as ccrs
 import cartopy.feature as cfeature
@@ -10,6 +12,146 @@ from datetime import datetime
 from enstools.feature.util.data_utils import pb_str_to_datetime
 from pathlib import Path
 import enstools.feature.identification.african_easterly_waves.configuration as cfg
+from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
+
+def get_kitweather_rain_cm():
+    rgb_colors = []
+    pathtotxtfile = '/home/iconeps/icon_data/additional_data/colorpalettes/'
+    filename_colorpalette = 'colorpalette_dyamond_prec_rate.txt'
+    with open(pathtotxtfile + filename_colorpalette, 'r') as f:
+        lines = f.readlines()
+    for i, line in enumerate(lines):
+        rgb_colors.append([float(line[0:3])/255, float(line[4:7])/255, float(line[8:11])/255, 1])
+    rgb_colors = [[1, 1, 1, 0]] + rgb_colors + [[0.35, 0, 0.4, 1]]
+    cmap = mpl.colors.ListedColormap(rgb_colors[1:-1]) # , name=colorpalette
+    cmap = cmap.with_extremes(bad='white', under=rgb_colors[0], over=rgb_colors[-1])
+
+    levels = [0.1,0.2,0.3,0.5,1,2,3,5,10,20,30,50]
+    norm = mpl.colors.BoundaryNorm(levels, cmap.N)
+
+    return levels, cmap, norm
+
+
+def crop_top_bottom_whitespace(path):
+
+    # pixels from image left where a vertical column is scanned from top and bottom for non-white pixels
+    x_scan_position = 450
+    add_bottom_delta = 20
+
+    im = Image.open(path)
+    image_array_y = np.where(np.asarray(im.convert('L')) < 255, 1, 0)[:, x_scan_position]
+    vmargins = [np.where(image_array_y[2:] == 1)[0][0] + 2 + 1,
+                image_array_y[:-2].shape[0] - np.where(image_array_y[:-2] == 1)[0][-1] + 2]
+    im_cropped = Image.new('RGBA',(im.size[0], im.size[1] - vmargins[0] - vmargins[1] + add_bottom_delta), (0, 0, 0, 0))
+    im_cropped.paste(im.crop((0, vmargins[0], im.size[0], im.size[1] - vmargins[1] + add_bottom_delta)), (0, 0))
+    im.close()
+    im_cropped.save(path, 'png')
+    im_cropped.close()
+
+    return
+
+
+## MAIN PLOTTING FUNC FOR KITWEATHER PLOTS
+def plot_ts_filtered_waves(wts_part_of_tracks, fig_name, ds=None, tp=None):
+    
+    from timeit import default_timer as timer
+    t1 = timer()
+
+    resolution = 1600
+    cbar_space_px = 80
+    subplotparameters = mpl.figure.SubplotParams(left=0, bottom=0, right=1 - cbar_space_px / resolution, top=1,
+                                             wspace=0, hspace=0)
+    fig, ax = plt.subplots(figsize=(resolution / 100, resolution / 100),
+                       dpi=100,
+                       subplotpars=subplotparameters,
+                       subplot_kw=dict(projection = ccrs.PlateCarree()))
+
+    extent = [-100, 35, -10, 35]
+
+
+    levels_rain, rain_cm, norm = get_kitweather_rain_cm()
+    distance_plot_to_cbar = 0.010
+    axins = ax.inset_axes([1 + distance_plot_to_cbar, 0.05, 0.015, 0.93],
+                      transform=ax.transAxes)
+    ticks_list = levels_rain
+    cbar = fig.colorbar(mpl.cm.ScalarMappable(cmap=rain_cm, norm=norm),
+                    cax=axins, extend='both', extendfrac=0.03,
+                    ticks=ticks_list)
+    axins.text(0.5, -0.06, 'mm/hr', transform=axins.transAxes,
+           horizontalalignment='left', verticalalignment='center')
+
+    t2 = timer()
+
+    if ds is not None:
+        # print("Before dec")
+        # streamplot_func = _add_transform_first_to_streamplot(ds.plot.streamplot)
+        # print("After dec")
+        ds.plot.streamplot(x='lon', y='lat', u='u', v='v', linewidth=0.6,
+                   arrowsize = 0.5,
+                   density=6,
+                   color='black') # , transform_first=True not working, or is already implemented. still slow.
+        
+    t3 = timer()
+
+    if tp is not None:
+        # transform to mm
+        tp.plot.contourf(levels=levels_rain, extend='max', subplot_kws={'transform_first': True},
+            cmap=rain_cm, norm=norm, add_colorbar=False)
+
+    t4 = timer()
+
+    # generate plot per pressure level, per time step
+
+    for obj_idx, node in enumerate(wts_part_of_tracks):
+        line_pts = node.object.properties.line_pts
+        line = patches.Path([[p.lon, p.lat] for p in line_pts])
+        patch = patches.PathPatch(line, linewidth=3, facecolor='none', edgecolor='crimson') # cmap(time_weight)
+        ax.add_patch(patch)
+
+    t5 = timer()
+
+    # ax.coastlines()
+    ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.3)
+    ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linewidth=0.3)
+    ax.set_extent(extent, crs=ccrs.PlateCarree())
+    ax.add_feature(cfeature.LAND.with_scale('50m'), facecolor=list(np.array([255, 225, 171])/255))
+
+    ax.get_xaxis().set_ticklabels([])
+    ax.get_yaxis().set_ticklabels([])
+
+    gl = ax.gridlines(crs=ccrs.PlateCarree(), draw_labels=True, linewidth=0.5, color='gray', alpha=0.5, linestyle='--')
+    gl.top_labels = False
+    gl.right_labels = False
+    gl.xformatter = LONGITUDE_FORMATTER
+    gl.yformatter = LATITUDE_FORMATTER
+
+    ax.set_title("")
+    fig.tight_layout()
+
+    plt.savefig(fig_name, format='png', backend='agg')
+
+    plt.figure().clear()
+    plt.close()
+    plt.cla()
+    plt.clf()
+
+    crop_top_bottom_whitespace(fig_name)
+
+    t6 = timer()
+    """
+    print("Init: " + str(t2 - t1))
+    print("Streamplot: " + str(t3 - t2))
+    print("Rain: " + str(t4 - t3))
+    print("Wavetroughs: " + str(t5 - t4))
+    print("Finalize: " + str(t6 - t5))
+
+    print("Saved to " +  fig_name)
+    exit()
+    """
+    print("Saved to " +  fig_name)
+    return
+
+
 
 # plots the wave state (all wavetroughs given specific timestep in a set) ts: pb2.Timestep
 def plot_wavetroughs(ts, fig_name, cv=None):
@@ -127,14 +269,10 @@ def plot_track(track, fn):
     return figure_name
 
 from collections import defaultdict
-def plot_differences(set_graph, tracks, cv=None): # TODO CV too?
+def plot_differences(set_graph, tracks, ds=None, tp=None, plot_prefix=None):
     # plot the differences of the total graph and the tracks
     # so check which WTs are part of a track and which have been dropped.
 
-    # TODO
-    #   join tracks list
-    #   set_graph elements not in tracks
-    #   for eaach timestep plot two mengen
     set_nodes = [e.parent for e in set_graph.graph.edges]
     is_in_set_nodes = [False] * len(set_nodes)
 
@@ -168,61 +306,28 @@ def plot_differences(set_graph, tracks, cv=None): # TODO CV too?
     dates_list = list(dates)
     dates_list.sort()
 
-    for date in dates_list:
-        fig_name = cfg.plot_dir + "part_of_wave_" + date.replace(':', '_') + ".png"
-        cv_ss = cv.sel(time=date)
-        plot_ts_part_of_track(wts_in_tracks[date], wts_not_in_tracks[date], fig_name, cv_ss)
-
-
-
-def plot_ts_part_of_track(wts_part_of_tracks, wt_not_part_of_tracks, fig_name, cv=None):
-
-    fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(11, 4), subplot_kw=dict(projection=ccrs.PlateCarree()))
-
-    x_ticks = [-100, -95, -85, -75, -65, -55, -45, -35, -25, -15, -5, 5, 15, 25, 35]
-    y_ticks = [0, 10, 20, 30]
-    extent = [-100, -45, -10, 35]
-
-    if cv is not None:
-        levelfc = np.asarray([0, 0.5, 1, 2, 3]) * 1e-5
-        cv.plot.contourf(levels=levelfc, vmin=0, extend='max', cmap='Blues')
-
-    # generate plot per pressure level, per time step
-
-    # colors per time step
-    # min_time = wave_thr_list[0].time.astype('float64')
-    # max_time = wave_thr_list[-1].time.astype('float64')
-    # cmap = matplotlib.cm.get_cmap('rainbow')
-    # color_wgts = np.linspace(0.0, 1.0, len(wave_thr_list))
-    # colors = ['red', 'yellow', 'green', 'blue', 'purple']
-
-    for obj_idx, node in enumerate(wts_part_of_tracks):
-        line_pts = node.object.properties.line_pts
-        line = patches.Path([[p.lon, p.lat] for p in line_pts])
-        patch = patches.PathPatch(line, linewidth=2, facecolor='none', edgecolor='lime') # cmap(time_weight)
-        ax.add_patch(patch)
-
-    for obj_idx, node in enumerate(wt_not_part_of_tracks):
-        line_pts = node.object.properties.line_pts
-        line = patches.Path([[p.lon, p.lat] for p in line_pts])
-        patch = patches.PathPatch(line, linewidth=2, facecolor='none', edgecolor='red') # cmap(time_weight)
-        ax.add_patch(patch)
+    if plot_prefix is None:
+        plot_prefix = cfg.plot_dir
+    # create subdirs if needed
+    plot_dir = '/'.join(plot_prefix.split('/')[:-1]) + '/'
+    os.makedirs(plot_dir, exist_ok=True)
 
-    ax.coastlines()
-    ax.add_feature(cfeature.BORDERS.with_scale('50m'))
-    ax.set_extent(extent, crs=ccrs.PlateCarree())
-    yt1 = ax.set_yticks(y_ticks, crs=ccrs.PlateCarree())
-    xt1 = ax.set_xticks(x_ticks, crs=ccrs.PlateCarree())
-
-    print("Save to " +  fig_name)
-    plt.savefig(fig_name, format='png')
-
-    plt.figure().clear()
-    plt.close()
-    plt.cla()
-    plt.clf()
+    for date in dates_list:
+        fig_name = plot_prefix + date[0:4] + date[5:7] + date[8:10] + "T" + date[11:13] + ".png"
+        ds_ss = ds.sel(time=date)
+        try:
+            tp_ss = tp.sel(time=date).tp
+
+        except (KeyError, AttributeError) as e:
+            print("No rain data for " + str(date))
+            tp_ss = None
+        plot_ts_filtered_waves(wts_in_tracks[date], fig_name, ds=ds_ss, tp=tp_ss) # wts_not_in_tracks[date], 
+        # except KeyError:
+        #     print("No rain data for " + str(date))
+            
+        #     tp_ss = None
+            # plot_ts_part_of_track(wts_in_tracks[date], wts_not_in_tracks[date], fig_name, ds=ds_ss, tp=tp_ss)
 
-    return
 
 
 def plot_track_from_graph(track_desc, fig_name_prefix, cv=None):
diff --git a/enstools/feature/identification/african_easterly_waves/processing.py b/enstools/feature/identification/african_easterly_waves/processing.py
index 141a4ed2337a9fe729f2f15bffba6dc97815b624..e29a3b18fb63a53e398c6dd95c55b9d75c81ebaf 100644
--- a/enstools/feature/identification/african_easterly_waves/processing.py
+++ b/enstools/feature/identification/african_easterly_waves/processing.py
@@ -2,13 +2,109 @@
 
 import numpy as np
 import xarray as xr
-import metpy.calc as mpcalc
-import itertools
+import math
+from enstools.feature.util.enstools_utils import get_u_var, get_v_var, get_vertical_dim, get_longitude_dim, \
+    get_latitude_dim
+
+
+# calculates the dx's and dy's for each grid cell
+# takes list of latitudes and longitudes as input and returns field with dimensions len(lats) x len(lons)
+def calculate_dx_dy(lats, lons):
+    lat_res = lats[1] - lats[0]
+    lon_res = lons[1] - lons[0]
+    nlat = len(lats)
+    nlon = len(lons)
+    lon_percent = (lon_res * nlon) / 360.0  # percentage of global longitudes. e.g. if 110W to 70E -> 0.5
+    lat_percent = (lat_res * nlat) / 180.0  # percentage of global latitudes
+    Re = 6378100
+
+    # field filled with the latitude value at each grid point
+    lat_f = np.tile(lats, (nlon, 1)).transpose()
+    # field filled with the longitude value at each grid point
+    lon_f = np.tile(lons, (nlat, 1))
+    # dx: circumference at current latitude  *  percentage of longitudes in dataset  /  amount of lon grid points
+    dx = np.cos(lat_f * math.pi / 180.0) * 2.0 * math.pi * Re * lon_percent / nlon
+    # dy: constant everywhere: half circumference  *  latitude percentage /  amount of lat points
+    dy = (lat_f * 0) + lat_percent * math.pi * Re / nlat
+
+    return dx, dy
 
 
-from matplotlib import pyplot as plt
-import cartopy.crs as ccrs
-import cartopy.feature as cfeature
+def compute_cv(dataset, u_str, v_str, cv_str):
+    xr.set_options(keep_attrs=True)  # assign coords keeps attributes
+
+    lon_str = get_longitude_dim(dataset)
+    lat_str = get_latitude_dim(dataset)
+
+    lats = dataset.coords[lat_str].data
+    lons = dataset.coords[lon_str].data
+
+    # be careful if your data is non-continuous by the chosen window (e.g. +120E..-120W)
+    # reorder axis for efficient numpy broadcasting
+    dataset = dataset.sortby(lat_str)
+    dataset = dataset.transpose(..., lat_str, lon_str)
+
+    dataset[cv_str] = xr.zeros_like(dataset[u_str], dtype=float)
+    dataset[cv_str].attrs = {'long_name': "Curvature Vorticity", 'units': "s**-1"}
+
+    # calculate dx and dy for each cell in grid in meters
+    dx, dy = calculate_dx_dy(lats, lons)
+
+    # Relative Vorticity = dv/dx - du/dy, use central differences
+    u_arr = dataset[u_str].data
+    v_arr = dataset[v_str].data
+    ndims = u_arr.ndim
+
+    # roll axes so we have a reference to each cell's neighbours
+    # ax[-1] = lon, ax[-2] = lat
+    # works as expected if longitude band is full 360 degrees. Rolling does exactly that.
+    v_xp = np.roll(v_arr, -1, axis=ndims - 1)  # roll -1 to get +1. v_xp = v(x+1)
+    v_xm = np.roll(v_arr, 1, axis=ndims - 1)
+    v_yp = np.roll(v_arr, -1, axis=ndims - 2)
+    v_ym = np.roll(v_arr, 1, axis=ndims - 2)
+
+    u_xp = np.roll(u_arr, -1, axis=ndims - 1)  # roll -1 to get +1
+    u_xm = np.roll(u_arr, 1, axis=ndims - 1)
+    u_yp = np.roll(u_arr, -1, axis=ndims - 2)
+    u_ym = np.roll(u_arr, 1, axis=ndims - 2)
+
+    # central differences:  (V(x+1)-V(x-1)) / 2x - (U(y+1)-U(y-1)) / 2y
+    RV = ((v_xp - v_xm) / (2 * dx)) - ((u_yp - u_ym) / (2 * dy))
+    # results verified to ERA5 vo-data
+
+    # split into shear + curvature: RV = -dV/dn + V/R
+    # shear vorticity:
+    # rate of change of wind speed in the direction of flow
+    # -dV/dn
+
+    # wind direction of this cell
+    ref_angle = np.arctan2(v_arr, u_arr)
+
+    ### METHOD 1 ### from analytical standpoint
+
+    sin_angle = np.sin(ref_angle)
+    cos_angle = np.cos(ref_angle)
+    # here is where the magic happens...
+    # to cartesian: dV/dn = - dV/dx * sin(phi) + dV/dy * cos(phi) ## n is normal to V, split it into x,y respecting the
+    # n-direction, where phi is the rotation angle of the natural coordinate system, this also is the angle of the
+    # wind vector
+    #
+    # we get the magnitude of shear as the projection of dV/dn onto the vector itself (direction e_t)
+    # with e_t = cos(phi)*e_x + sin(phi)*e_y , so:
+    # dV/dn * e_t = du/dx * (-sin*cos) + du/dy cos^2 + dv/dx *(-sin^2) + dv/dy (cos*sin)
+    SV = (u_xp - u_xm) / (2 * dx) * (-sin_angle * cos_angle) + \
+         (u_yp - u_ym) / (2 * dy) * (cos_angle ** 2) + \
+         (v_xp - v_xm) / (2 * dx) * (-(sin_angle ** 2)) + \
+         (v_yp - v_ym) / (2 * dy) * (sin_angle * cos_angle)
+    SV = -SV  # -dV/dn
+
+    # remainder is CV
+    CV = RV - SV
+    dataset[cv_str].values = CV
+
+    xr.set_options(keep_attrs='default')  # assign coords keeps attributes
+    return dataset
+
 
 import math
 from enstools.feature.util.enstools_utils import get_u_var, get_v_var, get_vertical_dim, get_longitude_dim, \
@@ -137,7 +233,8 @@ def populate_object(obj_props, path):
             max_lat = v[1]
 
         if v_idx > 0:
-            dist_deg = dist_deg + (((path.vertices[v_idx - 1][0] - v[0]) ** 2 + (path.vertices[v_idx - 1][1] - v[1]) ** 2) ** 0.5)
+            dist_deg = dist_deg + (
+                        ((path.vertices[v_idx - 1][0] - v[0]) ** 2 + (path.vertices[v_idx - 1][1] - v[1]) ** 2) ** 0.5)
 
     # bounding box
     obj_props.bb.min.lat = min_lat
@@ -149,5 +246,3 @@ def populate_object(obj_props, path):
 
 # identify troughs in data (should contain U,V,cv), based on the cv climatology
 # def identify_troughs(data, cv_clim, cfg):
-
-
diff --git a/enstools/feature/identification/african_easterly_waves/run_identify.py b/enstools/feature/identification/african_easterly_waves/run_identify.py
index c5d2c8b68f6b1bf3a01c134f9dba1bbf3883bcdc..fee56a092c6c9e97b8ce46e86d73af7d60dc16a4 100644
--- a/enstools/feature/identification/african_easterly_waves/run_identify.py
+++ b/enstools/feature/identification/african_easterly_waves/run_identify.py
@@ -1,27 +1,57 @@
+#!/usr/bin/env python
+
 # Usage Example
 from enstools.feature.pipeline import FeaturePipeline
 from enstools.feature.identification.african_easterly_waves import AEWIdentification
 from enstools.feature.tracking.african_easterly_waves import AEWTracking
-from datetime import timedelta
+from datetime import timedelta, datetime
 from enstools.feature.identification._proto_gen import african_easterly_waves_pb2
 from os.path import expanduser, join
 from enstools.feature.util.graph import DataGraph
 from enstools.feature.identification.african_easterly_waves.plotting import plot_differences, plot_track, plot_track_in_ts, plot_timesteps_from_desc, plot_tracks_from_desc
 import enstools.feature.identification.african_easterly_waves.configuration as cfg
-import sys
+import os, sys, glob, shutil
 from enstools.feature.util.data_utils import get_subset_by_description
+import xarray as xr
+xr.set_options(keep_attrs=True)
+import numpy as np
+from pprint import pprint
+
+
 
 pipeline = FeaturePipeline(african_easterly_waves_pb2, processing_mode='2d')
 
 # in_files_all_cv_data = cfg.cv_data_ex
-in_file = cfg.in_files
-out_dir = cfg.out_dir
 
-if len(sys.argv) > 1:
-    proc_summer_of_year = int(sys.argv[1])
-    if len(sys.argv) > 2:
-        proc_month_of_year = int(sys.argv[2])
+if len(sys.argv) >= 3 and sys.argv[1] == '-kw':
+    from kwutil import *
+    print("Executing in kitweather mode...")
+    # kitweather: use last 7 days of analysis and the ecmwf forecast
     
+    run = None
+    if len(sys.argv) == 4:
+        run = sys.argv[3]
+
+    if sys.argv[2] == 'ecmwf_fc':
+        ds, run = get_ecmwf_forecast(run=run, include_analysis_delta=cfg.timedelta_ana, add_prec_rate=True)
+    elif sys.argv[2] == 'icon_fc':
+        ds, run = get_icon_forecast(run=run, include_analysis_delta=cfg.timedelta_ana, add_prec_rate=True)
+    elif sys.argv[2] == 'gfs_fc':
+        ds, run = get_gfs_forecast(run=run, include_analysis_delta=cfg.timedelta_ana, add_prec_rate=True)
+    else:
+        print("Unknown command line parameter " + sys.argv[2] + ", expected ecmwf_fc or icon_fc.")
+        exit(1)
+
+    data_ds = ds[0]
+    rain_ds = None if len(ds) == 1 else ds[1]
+    print("Done collecting files.")
+
+    pipeline.set_data(data_ds)
+else:
+    in_file = cfg.in_files
+    out_dir = cfg.out_dir
+    pipeline.set_data_path(in_file)
+
 # init AEWIdentification strategy, can take different parameters
 i_strat = AEWIdentification(wt_out_file=False, cv='cv') # , year_summer=proc_summer_of_year, month=proc_month_of_year)
 t_strat = AEWTracking()
@@ -29,14 +59,13 @@ t_strat = AEWTracking()
 pipeline.set_identification_strategy(i_strat)
 pipeline.set_tracking_strategy(t_strat)
 
-pipeline.set_data_path(in_file)
-
 # execute pipeline
 pipeline.execute()
 
 od = pipeline.get_object_desc()
 
 for trackable_set in od.sets:
+
     # generate graph out of tracked data
     g = DataGraph(trackable_set, t_strat)
 
@@ -58,9 +87,40 @@ for trackable_set in od.sets:
     plot_differences(g, tracks, cv=ds_set.cv)
 
 
+# no out data besides plots on kitweather
+if sys.argv[1] == '-kw':
+    # delete old plots
+    subdirs = [dI for dI in os.listdir(plot_dir) if os.path.isdir(os.path.join(plot_dir,dI))]
+    for sd in subdirs: # for each subdir in plot dir
 
-# out_netcdf_path = data_path + '_streamers.nc'
+        if not sd == run and datetime.fromtimestamp(os.path.getmtime(os.path.join(plot_dir, sd))) < datetime.now() - timedelta(days=7): # not touched in a week? delete it.
+            print("Removing directory " + str(os.path.join(plot_dir, sd)))
+            shutil.rmtree(os.path.join(plot_dir, sd))
 
+
+    # All done. Update text file containing time of latest finished run.
+    if os.path.exists(cfg.plot_dir_ecmwf + run) and os.path.exists(cfg.plot_dir_icon + run) and os.path.exists(cfg.plot_dir_gfs + run):
+        print("Run " + run + " done for ECMWF, ICON, GFS. Update latest run info file.") 
+        yyyymmddhh = run[4:]
+
+        latest_run_file_path = cfg.latest_run_dir + cfg.latest_run_info_file_name
+
+        with open(latest_run_file_path, 'w+') as info_file:
+            info_file.write(yyyymmddhh)
+        
+    # All done. scp data over to webserver.
+    # TODO when port 22 free test.
+    # TODO improve plotting performance
+    """
+    path_webserver = '/home/iconeps/Data3/plots/ecmwf/aew_prediction_maps/'
+    print('scp -r ' + cfg.plot_dir + time_dir + '/ ' + 'iconeps@imk-tss-web.imk-tro.kit.edu:' + path_webserver)
+    os.system('scp -r ' + cfg.plot_dir + time_dir + '/ ' + 'iconeps@imk-tss-web.imk-tro.kit.edu:' + path_webserver)
+    os.system('scp ' + cfg.latest_run_info_file + ' iconeps@imk-tss-web.imk-tro.kit.edu:' + path_webserver)
+    """
+    exit()
+
+# out_netcdf_path = data_path + '_streamers.nc'
+"""
 if len(sys.argv) == 1:
     out_json_path = out_dir + 'aew_desc.json'
     out_dataset_path = out_dir + '05_wt.nc'
@@ -72,12 +132,6 @@ else:
     out_json_path = out_dir + 'aew_desc_' + str(proc_summer_of_year) + '_' + m_str + '.json'
     out_dataset_path = out_dir + '05_wt_' + str(proc_summer_of_year) + '_' + m_str + '.nc'
     
-
+"""
 
 pipeline.save_result(description_type='json', description_path=out_json_path) # , dataset_path=out_dataset_path) # dataset_path=out_dataset_path,
-# , description_path=out_json_path, graph_path=out_graph_path
-
-# print("Plot.")
-# plot_timesteps_from_desc(od, pipeline.get_data())
-# plot_tracks_from_desc(od, None)
-
diff --git a/enstools/feature/util/enstools_utils.py b/enstools/feature/util/enstools_utils.py
index 437edc16a4244f6a09a6479f8402476c8d0237c6..d8923695a6ca20535a77ea1d274a3bccf3707f7e 100644
--- a/enstools/feature/util/enstools_utils.py
+++ b/enstools/feature/util/enstools_utils.py
@@ -78,6 +78,22 @@ def get_longitude_dim(ds):
             return lon_name
     return None
 
+def get_u_var(ds):
+    u_names = ["u", "U"]
+    for u_name in u_names:
+        if u_name in ds.data_vars:
+            logging.debug("get_u_dim: found name '%s'" % u_name)
+            return u_name
+    return None
+
+def get_v_var(ds):
+    v_names = ["v", "V"]
+    for v_name in v_names:
+        if v_name in ds.data_vars:
+            logging.debug("get_v_dim: found name '%s'" % v_name)
+            return v_name
+    return None
+
 
 def get_u_var(ds):
     u_names = ["u", "U"]
@@ -115,7 +131,7 @@ def get_vertical_dim(ds):
     v_names = ["pres", "p", "lev", "level", "isobaric", "layer", "hybrid", "height", "height_2", "th_level", "plev"]
     for v_name in v_names:
         if v_name in ds.dims:
-            logging.debug("get_longitude_dim: found name '%s'" % v_name)
+            logging.debug("get_vertical_dim: found name '%s'" % v_name)
             return v_name
     return None